View Source Resourceful.Registry (Resourceful v0.1.5)
Link to this section Summary
Functions
Instances of Resourceful.Type
are intended to be used in conjunction with a
registry in most circumstances. The application, and even the client, will
likely understand a resource type by its string name/identifier. Types
themselves, when associated with a registry, will be able to reference each
other as well, which forms the basis for relationships.
Builds a field graph for a Resourceful.Type
. Since types have a max_depth
,
all possible graphed fields can be computed and cached at compile time when
using a registry. This allows nested fields to be treated like local fields in
the sense that they are available in a flat map.
A name can be optionally passed to the type/2
macro. If provided, this name
will override the name of the resource created in provided block.
Assigns the resource specified in the block
and makes it part of the
registry. If name
is provided, it will rename the resource and use that
name
as the key.
Ensures a value is a Resourceful.Type
and that no type of the same name
exists in the map. Raises an exception if both conditions are not met.
Link to this section Functions
Instances of Resourceful.Type
are intended to be used in conjunction with a
registry in most circumstances. The application, and even the client, will
likely understand a resource type by its string name/identifier. Types
themselves, when associated with a registry, will be able to reference each
other as well, which forms the basis for relationships.
A module using the Registry
behaviour becomes a key/value store.
defresourcefultype/1
allows the types to be evaluated entirely at compile
time.
@spec build_field_graph( %{ required(String.t()) => %Resourceful.Type{ cache: term(), fields: term(), id: term(), max_depth: term(), max_filters: term(), max_sorters: term(), meta: term(), name: term(), registry: term() } }, String.t() ) :: Resourceful.Type.field_graph()
Builds a field graph for a Resourceful.Type
. Since types have a max_depth
,
all possible graphed fields can be computed and cached at compile time when
using a registry. This allows nested fields to be treated like local fields in
the sense that they are available in a flat map.
For example, a song type would have a title
field. Once graphed, it would
also have an album.title
field. If the depth was set to 2, access to a field
like album.artist.name
would also be available.
This prevents a lot of recursion logic from being applied at every lookup and by instecting the field graph for a type it's easy to see all of the possible mappings.
Graphed fields are wrapped in a Resourceful.Type.GraphedField
struct which
contains relational information about the field in addition to the field data
itself.
See Resourceful.Type.max_depth/2
for information about what is intended to
be included in a field graph based on the depth setting.
do_build_field_graph(field_graph, types_map, type, depth, parent, name_prefix, map_to_prefix)
View Source@spec fetch_field_graph!( map(), String.t() | %Resourceful.Type{ cache: term(), fields: term(), id: term(), max_depth: term(), max_filters: term(), max_sorters: term(), meta: term(), name: term(), registry: term() } ) :: %{ required(String.t()) => %Resourceful.Type.GraphedField{ field: term(), map_to: term(), name: term(), parent: term(), query_alias: term() } }
@spec fetch_field_graph( map(), String.t() | %Resourceful.Type{ cache: term(), fields: term(), id: term(), max_depth: term(), max_filters: term(), max_sorters: term(), meta: term(), name: term(), registry: term() } ) :: {:ok, %{ required(String.t()) => %Resourceful.Type.GraphedField{ field: term(), map_to: term(), name: term(), parent: term(), query_alias: term() } }} | Resourceful.Error.contextual()
@spec maybe_put_name( %Resourceful.Type{ cache: term(), fields: term(), id: term(), max_depth: term(), max_filters: term(), max_sorters: term(), meta: term(), name: term(), registry: term() }, String.t() | nil ) :: %Resourceful.Type{ cache: term(), fields: term(), id: term(), max_depth: term(), max_filters: term(), max_sorters: term(), meta: term(), name: term(), registry: term() }
A name can be optionally passed to the type/2
macro. If provided, this name
will override the name of the resource created in provided block.
Assigns the resource specified in the block
and makes it part of the
registry. If name
is provided, it will rename the resource and use that
name
as the key.
If block
does not result in a Resourceful.Type
an exception will be
raised.
@spec validate_type!(any(), %{ required(String.t()) => %Resourceful.Type{ cache: term(), fields: term(), id: term(), max_depth: term(), max_filters: term(), max_sorters: term(), meta: term(), name: term(), registry: term() } }) :: %Resourceful.Type{ cache: term(), fields: term(), id: term(), max_depth: term(), max_filters: term(), max_sorters: term(), meta: term(), name: term(), registry: term() }
Ensures a value is a Resourceful.Type
and that no type of the same name
exists in the map. Raises an exception if both conditions are not met.