Server library to build JSON:API compliant REST APIs.
This library currently implements version 1.0 of the JSON:API specification.
Add the following line to your mix.deps file with the desired version to install jsonapi_plug.
defp deps do [
...
{:jsonapi_plug, "~> 1.0"}
...
]
You start by declaring one or more APIs. APIs are collections of endpoints that share a common configuration:
defmodule MyApp.API do
use JSONAPIPlug.API, otp_app: :my_app
endSee the JSONAPIPlug.API module documentation to learn how to customize your APIs
via application configuration of your app.
In order to parse JSON:API requests from clients you need to add the JSONAPIPlug.Plug plug to each of your plug pipelines or phoenix controllers handling requests for a specific resource:
defmodule MyApp.PostsController do
...
plug JSONAPIPlug.Plug, api: MyApp.API, resource: MyApp.PostResource
...
endThis will take care of ensuring JSON:API specification compliance and will return errors for invalid requests.
The :api option expects a module using JSONAPI.API for configuration.
The :resource option expects a module using JSONAPIPlug.Resource to convert to/from JSON:API format.
When requests are processed, the :jsonapi_plug connection private field is populated with the parsed request.
See the JSONAPIPlug.Plug module documentation for usage and options.
To start serving responses, you need to have some data to return to clients:
defmodule MyApp.Post do
@type t :: %__MODULE__{id: pos_integer(), body: String.t(), title: String.t()}
@enforce_keys [:id, :body, :title]
defstruct [:id, :body, :title]
endand define a resource module to render your resource:
defmodule MyApp.PostResource do
use JSONAPIPlug.Resource,
type: "post",
attributes: [
title: nil,
text: nil,
excerpt: [serialize: fn %Post{} = post, _conn -> String.slice(post.body, 0..5) end]
]
@impl JSONAPIPlug.Resource
def meta(%Post{} = post, _conn), do: %{slug: to_slug(post.title)}
endTo use the resource module in Phoenix, just call render and pass the data from your controller:
defmodule MyAppWeb.PostsController do
...
plug JSONAPIPlug.Plug, api: MyApp.API, resource: MyApp.PostResource
...
def create(%Conn{private: %{jsonapi_plug: jsonapi_plug}} = conn, params) do
post = ...create a post using jsonapi_plug parsed parameters...
render(conn, "create.json", %{data: post})
end
def index(%Conn{private: %{jsonapi_plug: jsonapi_plug}} = conn, _params) do
posts = ...load data using jsonapi_plug parsed parameters...
render(conn, "index.json", %{data: posts})
end
def show(%Conn{private: %{jsonapi_plug: jsonapi_plug} = conn, _params) do
post = ...load data using jsonapi_plug parsed parameters...
render(conn, "show.json", %{data: post})
end
def udate(%Conn{private: %{jsonapi_plug: jsonapi_plug}} = conn, params) do
post = ...update a post using jsonapi_plug parsed parameters...
render(conn, "update.json", %{data: post})
end
endIf you have a Plug application, you can call JSONAPIPlug.Resource.render/5 to generate a JSONAPI.Document with your data for the client. The structure is serializable to JSON with Jason.
See the JSONAPIPlug.Plug and JSONAPIPlug.Resource modules documentation for more information.
- This project was born as a fork of the jsonapi library but has since been completely rewritten and is now a completely different project.
- PRs for new features, bug fixes, documentation and tests are welcome
- If you are proposing a large feature or change, please open an issue for discussion