View Source Resourceful.Registry (Resourceful v0.1.3)

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.

Link to this function

build_field_graph(types_map, type_name)

View Source
@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.

Link to this function

do_build_field_graph(field_graph, types_map, type, depth, parent, name_prefix, map_to_prefix)

View Source
@spec fetch!(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()
}
@spec fetch(map(), String.t()) ::
  {:ok,
   %Resourceful.Type{
     cache: term(),
     fields: term(),
     id: term(),
     max_depth: term(),
     max_filters: term(),
     max_sorters: term(),
     meta: term(),
     name: term(),
     registry: term()
   }}
  | Resourceful.Error.contextual()
Link to this function

fetch_field_graph!(field_graphs, name)

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()
  }
}
Link to this function

fetch_field_graph(field_graphs, name)

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()
    }
) ::
  {:ok,
   %{
     required(String.t()) => %Resourceful.Type.GraphedField{
       field: term(),
       map_to: term(),
       name: term(),
       parent: term(),
       query_alias: term()
     }
   }}
  | Resourceful.Error.contextual()
Link to this function

maybe_put_name(type, name)

View Source
@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.

Link to this macro

type(name \\ nil, list)

View Source (macro)

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.

Link to this function

validate_type!(type, types)

View Source
@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.