AshJsonApi

AshJsonApi allows you to take resources created with Ash and build complete JSON:API compliant endpoints with just a few lines of code.

Here is how it fits into an app and what it does: Architecture Sketch

As you can see, Ash takes care of all of the data related work for a request (CRUD, Sorting, Filtering, Pagination, Side Loading, and Authorization) while AshJsonApi more or less replaces controllers and serializers.

The beauty of putting all of that data functionality into a non-web layer (Ash) is that it can be used in many contexts. A JSON:API is one context - but there are others such as GraphQL or just using an Ash Resource from other code within an Application. The decoupling of the web from data layers is why AshJsonApi is it's own hex package, as opposed to just a module within Ash.

Installation

TODO

Usage

Assume you have already built a resource using Ash such as this Post resource:

defmodule Post do
  use Ash.Resource, name: "posts", type: "post"
  use AshJsonApi.JsonApiResource
  use Ash.DataLayer.Postgres

  actions do
    read :default,
      authorization_steps: [
        allow_if: user_is(:admin)
      ]

    create :default,
      authorization_steps: [
        allow_if: user_is(:admin)
      ]
    
  end

  attributes do
    attribute :name, :string
  end

  relationships do
    belongs_to :author, Author
  end
end

As you can see, the resource takes care of interacting with the database, setting up attributes and relationships, as well as specifying actions (CRUD) that can be performed on the resource. What is now needed is to add a configuration for how this resource will interact with JSON:API

defmodule Post do
  ...
  
  json_api do
    routes do
      # Add a `GET /posts/:id` route, that calls into the :read action called :default
      get :default
      # Add a `GET /posts` route, that calls into the :read action called :default
      index :default
    end

    # Expose these attributes in the API
    fields [:name]
  end

  ...

TODO