Calcinator

Calcinator provides a standardized interface for processing JSONAPI request that is transport neutral. CSD uses it for both API controllers and RPC servers.

Calcinator uses Alembic to validate JSONAPI documents passed to the action functions in Calcinator. Calcinator supports the JSONAPI CRUD-style actions:

  • create
  • delete
  • get_related_resource
  • index
  • show
  • show_relationship
  • update

Each action expects to be passed a %Calcinator{}. The struct allow Calcinator to support converting JSONAPI includes to associations (associations_by_include), authorization (authorization_module and subject), Ecto.Schema.t interaction (resources_module), and JSONAPI document rendering (view_module).

Authorization

%Calcinator{} authorization_modules need to implement the Calcinator.Authorization behaviour.

  • can?(subject, action, target) :: boolean
  • filter_associations_can(target, subject, action) :: target
  • filter_can(targets :: [target], subject, action) :: [target]

The can?(suject, action, target) :: boolean matches the signature of the Canada protocol, but it is not required.

Resources

Calcinator.Resources is a behaviour to supporting standard CRUD actions on an Ecto-based backing store. This backing store does not need to be a database that uses Ecto.Repo. At CSD, we use Calcinator.Resources to hide the differences between Ecto.Repo backed Ecto.Schema.t and RPC backed Ecto.Schema.t (where we use Ecto to do the type casting.)

Because Calcinator.Resources need to work as an interface for both Ecto.Repo and RPC backed resources, the callbacks and returns need to work for both, so all Calcinator.Resources implementations need to support allow_sandbox_access and sandboxed? used for concurrent Ecto.Repo tests, but they also can return RPC error messages like {:error, :bad_gateway} and {:error, :timeout}.

Pagination

The list callback instead of returning just the list of resources, also accepts and returns (optional) pagination information. The pagination param format is documented in Calcinator.Resources.Page.

In addition to pagination in page, Calcinator.Resources.query_options supports associations for JSONAPI includes (after being converted using %Calcinator{} associations_by_include), filters for JSONAPI filters that are passed through directly, and sorts for JSONAPI sort.

Installation

If available in Hex, the package can be installed as:

  1. Add calcinator to your list of dependencies in mix.exs:

    def deps do
      [{:calcinator, "~> 1.0.0"}]
    end
  2. Ensure calcinator is started before your application:

    def application do
      [applications: [:calcinator]]
    end