Skip to content

Commit e764f25

Browse files
committed
docs: update docs to factor in getting started guides
1 parent 0ca812a commit e764f25

File tree

2 files changed

+111
-85
lines changed

2 files changed

+111
-85
lines changed

documentation/tutorials/getting-started-with-ash-json-api.md

Lines changed: 111 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,22 @@
11
# Getting started with AshJsonApi
22

3-
The easiest set up involves using Phoenix, but it should be roughly the same to set up an application using only Plug. We are showing examples using Phoenix Routers.
3+
## Installing AshJsonApi
44

5-
The resulting JSON APIs follow the specifications from https://jsonapi.org/.
5+
<!-- tabs-open -->
66

7-
To add a JSON API, we need to do the following things:
7+
### Using Igniter (recommended)
88

9-
1. Add the `:ash_json_api` package to your dependencies.
10-
2. Add the JSON API extension to your `Ash.Resource` and `Ash.Domain` modules.
11-
3. Tell Ash which Resource actions expose over the API.
12-
4. Add a custom media type as specified by https://jsonapi.org/.
13-
5. Create a router module
14-
6. Make your router available in your applications main router.
9+
```sh
10+
mix igniter.install ash_json_api
11+
```
12+
13+
### Manually
14+
15+
This manual setup branches off from the [Getting Started with Ash](https://hexdocs.pm/ash/get-started.html) guide.
16+
If you aren't starting from there, replace the application name, `Helpdesk`, with your application name,
17+
and replace the `Ash.Domain` name, `Helpdesk.Support` with a domain or domains from your own application.
1518

16-
## Add the ash_json_api dependency
19+
#### Add the ash_json_api dependency
1720

1821
In your mix.exs, add the Ash JSON API dependency:
1922

@@ -26,16 +29,113 @@ In your mix.exs, add the Ash JSON API dependency:
2629
end
2730
```
2831

32+
#### Accept json_api content type
33+
34+
Add the following to your `config/config.exs`.
35+
36+
```elixir
37+
# config/config.exs
38+
config :mime, :types, %{
39+
"application/vnd.api+json" => ["json"]
40+
}
41+
```
42+
43+
This configuration is required to support working with the JSON:API custom mime type.
44+
45+
After adding the configuration above, compiling the project might throw an error:
46+
47+
```
48+
ERROR! the application :mime has a different value set for key :types during runtime compared to compile time.
49+
```
50+
51+
This can happen if `:mime` was already compiled before the configuration was changed and can be
52+
fixed by running
53+
54+
```
55+
mix deps.compile mime --force
56+
```
57+
58+
#### Create a router
59+
60+
Create a separate Router Module to work with your Domains. It will generate the routes for
61+
your Resources and provide the functions you would usually have in a Controller.
62+
63+
We will later forward requests from your Applications primary (Phoenix) Router to you Ash JSON API Router.
64+
65+
```elixir
66+
defmodule HelpdeskWeb.JsonApiRouter do
67+
use AshJsonApi.Router,
68+
# The api modules you want to serve
69+
domains: [Module.concat(["Helpdesk.Support"])],
70+
# optionally an open_api route
71+
open_api: "/open_api"
72+
end
73+
```
74+
75+
> ### Whats up with `Module.concat/1`? {: .info}
76+
>
77+
> This `Module.concat/1` prevents a [compile-time dependency](https://dashbit.co/blog/speeding-up-re-compilation-of-elixir-projects) from this router module to the domain modules. It is an implementation detail of how `forward/2` works that you end up with a compile-time dependency on the schema, but there is no need for this dependency, and that dependency can have _drastic_ impacts on your compile times in certain scenarios.
78+
79+
Additionally, your Resource requires a type, a base route and a set of allowed HTTP methods and what action they will trigger.
80+
81+
#### Add the routes from your domain module(s)
82+
83+
To make your Resources accessible to the outside world, forward requests from your Phoenix router to the router you created for your domains.
84+
85+
For example:
86+
87+
```elixir
88+
scope "/api/json" do
89+
pipe_through(:api)
90+
91+
forward "/helpdesk", HelpdeskWeb.JsonApiRouter
92+
end
93+
```
94+
95+
<!-- tabs-close -->
96+
2997
## Configure your Resources and Domain and expose actions
3098

31-
Both your Resource and domain need to use the extension for the JSON API.
99+
These examples are based off of the [Getting Started with Ash](https://hexdocs.pm/ash/get-started.html) guide.
100+
101+
### Add the AshJsonApi extension to your domain and resource
102+
103+
<!-- tabs-open -->
104+
105+
### Using Igniter (recommended)
106+
107+
To set up an existing resource of your own with `AshJsonApi`, run:
108+
109+
```sh
110+
mix ash.patch.extend Your.Resource.Name json_api
111+
```
112+
113+
### Manually
114+
115+
Add to your domain:
32116

33117
```elixir
34118
defmodule Helpdesk.Support do
35119
use Ash.Domain, extensions: [AshJsonApi.Domain]
36120
...
37121
```
38122

123+
And to your resource:
124+
125+
```elixir
126+
defmodule Helpdesk.Support.Ticket do
127+
use Ash.Resource, extensions: [AshJsonApi.Resource]
128+
# ...
129+
json_api do
130+
type "ticket"
131+
end
132+
end
133+
```
134+
135+
<!-- tabs-close -->
136+
137+
## Define Routes
138+
39139
Routes can be defined on the resource or the domain. If you define them on the domain (which is our default recommendation), the resource in question must still use the `AshJsonApi.Resource` extension, and define its own type.
40140

41141
### Defining routes on the domain
@@ -96,79 +196,6 @@ end
96196
Check out the [AshJsonApi.Resource documentation on
97197
Hex](https://hexdocs.pm/ash_json_api/AshJsonApi.Resource.html) for more information.
98198

99-
## Accept json_api content type
100-
101-
Add the following to your `config/config.exs`.
102-
103-
```elixir
104-
# config/config.exs
105-
config :mime, :types, %{
106-
"application/vnd.api+json" => ["json"]
107-
}
108-
```
109-
110-
This configuration is required to support working with the JSON:API custom mime type.
111-
112-
After adding the configuration above, compiling the project might throw an error:
113-
114-
```
115-
ERROR! the application :mime has a different value set for key :types during runtime compared to compile time.
116-
```
117-
118-
This can happen if `:mime` was already compiled before the configuration was changed and can be
119-
fixed by running
120-
121-
```
122-
mix deps.compile mime --force
123-
```
124-
125-
## Create a router
126-
127-
Create a separate Router Module to work with your Domains. It will generate the routes for
128-
your Resources and provide the functions you would usually have in a Controller.
129-
130-
We will later forward requests from your Applications primary (Phoenix) Router to you Ash JSON API Router.
131-
132-
```elixir
133-
defmodule HelpdeskWeb.JsonApiRouter do
134-
use AshJsonApi.Router,
135-
# The api modules you want to serve
136-
domains: [Module.concat(["Helpdesk.Support"])],
137-
# optionally a json_schema route
138-
json_schema: "/json_schema",
139-
# optionally an open_api route
140-
open_api: "/open_api"
141-
end
142-
```
143-
144-
> ### Whats up with `Module.concat/1`? {: .info}
145-
>
146-
> This `Module.concat/1` prevents a [compile-time dependency](https://dashbit.co/blog/speeding-up-re-compilation-of-elixir-projects) from this router module to the domain modules. It is an implementation detail of how `forward/2` works that you end up with a compile-time dependency on the schema, but there is no need for this dependency, and that dependency can have _drastic_ impacts on your compile times in certain scenarios.
147-
148-
Additionally, your Resource requires a type, a base route and a set of allowed HTTP methods and what action they will trigger.
149-
150-
## Add the routes from your domain module(s)
151-
152-
To make your Resources accessible to the outside world, forward requests from your Phoenix router to the router you created for your domains.
153-
154-
For example:
155-
156-
```elixir
157-
scope "/api/json" do
158-
pipe_through(:api)
159-
160-
forward "/helpdesk", HelpdeskWeb.JsonApiRouter
161-
end
162-
```
163-
164-
With the above configuration, the path to "get" your Tickets resource would be: `/api/json/helpdesk/tickets`, where:
165-
166-
- "/api/json", which comes from the `scope` in the router.
167-
168-
- "/helpdesk", which comes from the `forward` in the scope.
169-
170-
- "/tickets", which comes from the Domain or the Resource's `json_api` configuration.
171-
172199
## Run your API
173200

174201
From here on out its the standard Phoenix behavior. Start your application with `mix phx.server`

lib/ash_json_api/igniter.ex

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ defmodule AshJsonApi.Igniter do
5858
"""
5959
use AshJsonApi.Router,
6060
domains: #{inspect(domains)},
61-
json_schema: "/json_schema",
6261
open_api: "/open_api"
6362
""",
6463
fn zipper ->

0 commit comments

Comments
 (0)