Packages
ash_json_api
0.20.0
1.7.1
1.7.0
1.6.6
1.6.5
1.6.4
1.6.3
1.6.2
1.6.1
1.6.0-rc.2
1.6.0-rc.1
1.6.0-rc.0
1.5.1
1.5.0
1.4.45
1.4.44
1.4.43
1.4.42
1.4.41
1.4.40
1.4.39
1.4.38
1.4.37
1.4.36
1.4.35
1.4.34
1.4.33
1.4.32
1.4.31
1.4.30
1.4.29
1.4.28
1.4.27
1.4.26
1.4.25
1.4.24
1.4.23
1.4.22
1.4.21
1.4.20
1.4.19
1.4.18
1.4.17
1.4.16
1.4.15
1.4.13
1.4.12
1.4.11
1.4.10
1.4.9
1.4.8
1.4.7
1.4.6
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.8
1.3.7
1.3.6
1.3.5
1.3.4
retired
1.3.3
1.3.2
1.3.1
1.3.0
1.2.2
1.2.1
1.2.0
1.1.2
1.1.1
1.1.0
1.0.0
1.0.0-rc.6
1.0.0-rc.5
1.0.0-rc.4
1.0.0-rc.3
1.0.0-rc.2
1.0.0-rc.1
1.0.0-rc.0
0.34.2
0.34.1
0.34.0
0.33.1
0.33.0
0.32.1
0.32.0
0.31.3
0.31.2
retired
0.31.1
0.31.0
0.30.1
0.30.0-rc.4
0.30.0-rc.3
0.30.0-rc.2
0.30.0-rc.1
0.30.0-rc.0
0.29.1
0.29.0
0.28.6
0.28.5
0.28.4
0.28.3
0.28.2
0.28.1
0.28.0
0.27.6
0.27.5
0.27.1
0.27.0
0.25.0
0.24.4
0.24.2
0.24.1
0.24.0
0.23.0
0.22.0
0.21.0
0.20.0
0.19.0
0.18.0
0.17.0
0.16.0
0.15.0
0.14.0
0.13.0
0.12.0
0.11.1
0.10.0
0.9.0
0.8.0
0.6.0
0.5.0
0.4.0
0.3.0
0.2.4
0.2.3
0.2.1
0.2.0
0.1.5
0.1.4
0.1.3
0.1.2
0.1.1
0.1.0
The JSON:API extension for the Ash Framework.
Current section
Files
Jump to
Current section
Files
lib/ash_json_api.ex
defmodule AshJsonApi do
@moduledoc """

An ash extension for building a JSON:API with ash resources.
## Usage
Assume you have already built a resource using [Ash](https://github.com/ash-project/ash) such as this Post resource:
```elixir
defmodule Post do
use Ash.Resource,
data_layer: Ash.DataLayer.Postgres
actions do
read :default
create :default
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
```elixir
defmodule Post do
use Ash.Resource,
data_layer: AshPostgres,
extensions: [AshJsonApi.Resource]
...
json_api do
routes do
base "/posts"
# 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
...
```
Then, update your API with the API extension and configuration:
```elixir
defmodule MyApp.Api do
use Ash.Api, extensions: [AshJsonApi.Api]
json_api do
...
end
end
```
See `AshJsonApi.Api` and `AshJsonApi.Resource` for the DSL documentation.
"""
alias Ash.Dsl.Extension
def prefix(api) do
Extension.get_opt(api, [:json_api], :prefix, nil, true)
end
def serve_schema?(api) do
Extension.get_opt(api, [:json_api], :serve_schema?, false, true)
end
def authorize?(api) do
Extension.get_opt(api, [:json_api], :authorize?, true, true)
end
def log_errors?(api) do
Extension.get_opt(api, [:json_api], :log_errors?, true, true)
end
defmacro forward(path, api, opts \\ []) do
quote bind_quoted: [path: path, api: api, opts: opts] do
case Code.ensure_compiled(api) do
{:module, module} ->
forward(path, :persistent_term.get({api, :ash_json_api, :router}, nil), opts)
_error ->
# We used to raise here, but this failing almost always implies
# a compilation error in the api, which will be more informative
# if we just let that be raised
:ok
end
end
end
def router(api) do
:persistent_term.get({api, :ash_json_api, :router}, nil)
end
end