Packages
ash_json_api
0.3.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 route(resource, criteria \\ %{}) do
resource
|> routes()
|> Enum.find(fn route ->
Map.take(route, Map.keys(criteria)) == criteria
end)
end
def type(resource) do
Extension.get_opt(resource, [:json_api], :type)
end
def routes(resource) do
Extension.get_entities(resource, [:json_api, :routes])
end
def fields(resource) do
Extension.get_opt(resource, [:json_api], :fields)
end
def includes(resource) do
Extension.get_opt(resource, [:json_api], :includes)
end
def prefix(api) do
Extension.get_opt(api, [:json_api], :prefix)
end
def serve_schema?(api) do
Extension.get_opt(api, [:json_api], :serve_schema?)
end
def authorize?(api) do
Extension.get_opt(api, [:json_api], :authorize?)
end
def router!(api) do
case Code.ensure_compiled(api) do
{:module, _module} ->
:persistent_term.get({api, :ash_json_api, :router}, nil)
error ->
raise "#{inspect(api)} was not compiled: #{inspect(error)}"
end
end
def base_route(resource) do
Extension.get_opt(resource, [:json_api, :routes], :base)
end
end