View Source Resourceful.Type.Attribute (Resourceful v0.1.4)

Attributes represent "value" fields for a given Resourceful.Type. This governs a few common operations:

casting-inputs

Casting Inputs

Values will often come in the form of strings from the edge. Attributes use Ecto's typecasting to cast inputs into proper datatype or return appropriate errors.

mapping-to-underlying-resources

Mapping to Underlying Resources

Generally speaking, outside representation of resources will use strings as keys on maps whereas internal structures tend to be atoms. Additionally, internal structures will often use snake case whereas external structures may take multiple forms (e.g. camel case or dasherized when dealing with JSON:API). Attributes map values to their appropriate internal keys.

configuring-queries

Configuring Queries

APIs may choose to restrict what attributes can be filtered and sorted. For instance, you make wish to only allow public queries against indexed attributes or none at all.

This allows the system restrict access and return meaningful errors when a client attempts to query against an attribute.

Link to this section Summary

Functions

Casts an input into an attribute's type. If cast_as_list is true, it will wrap the attribute's type in a list. This is specifically for dealing with filters that take a list of values.

Creates a contextual error wthe attribute's name in the context.

Sets the filter? key for an attribute. Collections cannot be filtered by an attribute unless this is set to true.

Sets the map_to key for an attribute. map_to is the key of the underlying map to use in place of the attribute's actual name. Unlike a name which can only be a string, this can be an atom or a string (dots allowed).

Sets the name for the attribute. This is the "edge" name that clients will interact with. It can be any string as long as it doesn't contain dots. This will also serve as its key name if used in conjunction with a Resourceful.Type which is important in that names must be unique within a type.

Creates a new attribute, coerces values, and sets defaults.

A shortcut for setting both filter? and sort? to the same value.

Sets the sort? key for an attribute. Collections cannot be sorted by an attribute unless this is set to true.

Sets the data type for casting. This must be an Ecto.Type or atom that works in its place such as :string.

Validates a filter against the attribute and the data given. It ensures the data type is correct for the operator and that the attribute allows filtering at all.

Validates a sorter against the attribute ensuring that sorting is allowed for the attribute.

Link to this section Functions

Link to this function

cast(attr_or_graph, input, cast_as_list \\ false)

View Source
@spec cast(Resourceful.Type.queryable(), any(), boolean()) ::
  {:ok, any()} | Resourceful.Error.t()

Casts an input into an attribute's type. If cast_as_list is true, it will wrap the attribute's type in a list. This is specifically for dealing with filters that take a list of values.

Link to this function

error(map, error_type, context \\ %{})

View Source

Creates a contextual error wthe attribute's name in the context.

@spec filter(
  %Resourceful.Type.Attribute{
    embedded_type: term(),
    filter?: term(),
    map_to: term(),
    name: term(),
    sort?: term(),
    type: term()
  },
  boolean()
) :: %Resourceful.Type.Attribute{
  embedded_type: term(),
  filter?: term(),
  map_to: term(),
  name: term(),
  sort?: term(),
  type: term()
}

Sets the filter? key for an attribute. Collections cannot be filtered by an attribute unless this is set to true.

@spec map_to(
  %Resourceful.Type.Attribute{
    embedded_type: term(),
    filter?: term(),
    map_to: term(),
    name: term(),
    sort?: term(),
    type: term()
  },
  atom() | String.t()
) :: %Resourceful.Type.Attribute{
  embedded_type: term(),
  filter?: term(),
  map_to: term(),
  name: term(),
  sort?: term(),
  type: term()
}

Sets the map_to key for an attribute. map_to is the key of the underlying map to use in place of the attribute's actual name. Unlike a name which can only be a string, this can be an atom or a string (dots allowed).

@spec name(
  %Resourceful.Type.Attribute{
    embedded_type: term(),
    filter?: term(),
    map_to: term(),
    name: term(),
    sort?: term(),
    type: term()
  },
  String.t()
) :: %Resourceful.Type.Attribute{
  embedded_type: term(),
  filter?: term(),
  map_to: term(),
  name: term(),
  sort?: term(),
  type: term()
}

Sets the name for the attribute. This is the "edge" name that clients will interact with. It can be any string as long as it doesn't contain dots. This will also serve as its key name if used in conjunction with a Resourceful.Type which is important in that names must be unique within a type.

Link to this function

new(name, type, opts \\ [])

View Source
@spec new(String.t(), atom(), keyword()) :: %Resourceful.Type.Attribute{
  embedded_type: term(),
  filter?: term(),
  map_to: term(),
  name: term(),
  sort?: term(),
  type: term()
}

Creates a new attribute, coerces values, and sets defaults.

@spec query(
  %Resourceful.Type.Attribute{
    embedded_type: term(),
    filter?: term(),
    map_to: term(),
    name: term(),
    sort?: term(),
    type: term()
  },
  boolean()
) :: %Resourceful.Type.Attribute{
  embedded_type: term(),
  filter?: term(),
  map_to: term(),
  name: term(),
  sort?: term(),
  type: term()
}

A shortcut for setting both filter? and sort? to the same value.

@spec sort(
  %Resourceful.Type.Attribute{
    embedded_type: term(),
    filter?: term(),
    map_to: term(),
    name: term(),
    sort?: term(),
    type: term()
  },
  boolean()
) :: %Resourceful.Type.Attribute{
  embedded_type: term(),
  filter?: term(),
  map_to: term(),
  name: term(),
  sort?: term(),
  type: term()
}

Sets the sort? key for an attribute. Collections cannot be sorted by an attribute unless this is set to true.

@spec type(
  %Resourceful.Type.Attribute{
    embedded_type: term(),
    filter?: term(),
    map_to: term(),
    name: term(),
    sort?: term(),
    type: term()
  },
  any()
) :: %Resourceful.Type.Attribute{
  embedded_type: term(),
  filter?: term(),
  map_to: term(),
  name: term(),
  sort?: term(),
  type: term()
}

Sets the data type for casting. This must be an Ecto.Type or atom that works in its place such as :string.

Link to this function

validate_filter(attr_or_graph, op, val)

View Source

Validates a filter against the attribute and the data given. It ensures the data type is correct for the operator and that the attribute allows filtering at all.

Link to this function

validate_sorter(attr_or_graph, order \\ :asc)

View Source
@spec validate_sorter(Resourceful.Type.queryable(), :asc | :desc) ::
  {:ok, Sort.t()} | Resourceful.Error.t()

Validates a sorter against the attribute ensuring that sorting is allowed for the attribute.