Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/lucacorti/jsonapi_plug
JSON:API library for Plug and Phoenix applications
https://github.com/lucacorti/jsonapi_plug
elixir elixir-lang elixir-library elixir-phoenix json-api
Last synced: about 1 month ago
JSON representation
JSON:API library for Plug and Phoenix applications
- Host: GitHub
- URL: https://github.com/lucacorti/jsonapi_plug
- Owner: lucacorti
- License: mit
- Created: 2022-08-21T14:17:56.000Z (about 2 years ago)
- Default Branch: main
- Last Pushed: 2024-09-29T10:14:01.000Z (about 2 months ago)
- Last Synced: 2024-09-30T09:01:56.856Z (about 2 months ago)
- Topics: elixir, elixir-lang, elixir-library, elixir-phoenix, json-api
- Language: Elixir
- Homepage: https://hexdocs.pm/jsonapi_plug
- Size: 947 KB
- Stars: 11
- Watchers: 4
- Forks: 3
- Open Issues: 10
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG-jsonapi.md
- License: LICENSE
Awesome Lists containing this project
README
# JSON:API library for Plug and Phoenix applications
Server library to build [JSON:API](http://jsonapi.org) compliant REST APIs.
## JSON:API Support
This library currently implements version `1.0` of the [JSON:API][json:api] specification.
However, to support resource creation alongside included resources, `JSON:API 1.1` `lid` is supported.## Documentation
- Full documentation can be found on [hexdocs.pm][jsonapi_plug-hexdocs]
For the `JSON:API` specification documentation as well as other client and server implementations:
- [JSON:API][json:api]
- [JSON:API Specification (v1.0)][json:api-1.0]
- [JSON:API Specification (v1.1)][json:api-1.1]## Quickstart
### Installation
Add the following line to your `mix.deps` file with the desired version to install `jsonapi_plug`.
```elixir
defp deps do [
...
{:jsonapi_plug, "~> 2.0"}
...
]
```### Upgrading
Upgrading the library should be safe for minor and patch vesion upgrades, it's still a good practice
to check the [changelog][changelog] for more information on the release content. For major version
upgrades, breaking changes should be expected, and the [upgrade guide][upgrade] contains instructions
on upgrading between major releases of the library.### Configuration
You start by declaring one or more APIs. APIs are collections of endpoints that
share a common configuration:```elixir
defmodule MyApp.API do
use JSONAPIPlug.API, otp_app: :my_app
end
```See the `JSONAPIPlug.API` module documentation to learn how to customize your APIs
via application configuration of your app.### Resources
To start accept requests and serving responses, you need to define `JSON:API` resources.
Resources can be any struct `@derive`-ing the `JSONAPIPlug.Resource` protocol:```elixir
defmodule MyApp.Post do
use Ecto.Schema@type t :: %__MODULE__{id: pos_integer(), body: String.t(), title: String.t()}
@derive {
JSONAPIPlug.Resource,
type: "post",
attributes: [:title, :text, :excerpt]
}
schema "posts" do
field :title
field :text
end...
end
```See `JSONAPIPlug.Resource` for the complete documentation of options you can pass to `@derive`,
including how to control serialization and deserialization, and add related resources.Also, three optional protocols are available to allow further customization of resources.
- Resource attribute custom serialization and deserialization: `JSONAPIPlug.Resource.Attribute`
- Resource link generation: `JSONAPIPlug.Resource.Links`
- Resource link generation: `JSONAPIPlug.Resource.Meta`### Usage with Phoenix
To serve JSON:API resources in Phoenix, you need to define routes in your router:
```elixir
defmodule MyAppWeb.Router do
...
resource "/posts", MyApp.PostsController, only: [:create, :index, :show]
patch "/posts/:id", MyApp.PostsController, :update
end
```In order to parse `JSON:API` requests from clients you need to add the `JSONAPIPlug.Plug` plug to each of your
phoenix controllers handling requests for a specific resource. This will take care of ensuring `JSON:API` request
compliance and will return errors for malformed requests.When a valid request processed, the `:jsonapi_plug` `Plug.Conn` private field will be populated in the controller.
You can learn all about advanced request handling, including custom filtering, relationships inclusion, pagination
and sparse fields support by reading the `JSONAPIPlug.Plug` module documentation.Once you receive a request in your controller and load data, you just call render to send a response:
```elixir
defmodule MyAppWeb.PostsController do
...
plug JSONAPIPlug.Plug, api: MyApp.API, path: "posts", resource: MyApp.Post
...def create(%Conn{private: %{jsonapi_plug: %JSONAPIPlug{} = jsonapi_plug}} = conn, params) do
post = ...create a post using jsonapi_plug parsed parameters...
render(conn, "create.json", %{data: post})
enddef index(%Conn{private: %{jsonapi_plug: %JSONAPIPlug{} = jsonapi_plug}} = conn, _params) do
posts = ...load data using jsonapi_plug parsed parameters...
render(conn, "index.json", %{data: post})
enddef show(%Conn{private: %{jsonapi_plug: %JSONAPIPlug{} = jsonapi_plug}} = conn, _params) do
post = ...load data using jsonapi_plug parsed parameters...
render(conn, "show.json", %{data: post})
enddef udate(%Conn{private: %{jsonapi_plug: %JSONAPIPlug{} = jsonapi_plug}} = conn, params) do
post = ...update a post using jsonapi_plug parsed parameters...
render(conn, "update.json", %{data: post})
end
end
```For phoenix to dispatch this for rendering you need to add this code to your `MyAppWeb` module:
```elixir
def MyAppWeb do
...def json_api do
quote do
use JSONAPIPlug.Phoenix.Component
end
end...
end
```and define a corresponding rendering template module:
```elixir
defmodule SibillWeb.PostsJSON do
@moduledoc falseuse MyAppWeb, :json_api
end
```alternatively you can skip these steps by calling `JSONAPIPlug.render/4` directly instead of `render/3` in you controller:
```elixir
...
def show(%Conn{private: %{jsonapi_plug: %JSONAPIPlug{} = jsonapi_plug}} = conn, _params) do
post = ...load data using jsonapi_plug parsed parameters...
JSONAPIPlug.render(conn, post \\ nil, meta \\ nil, options \\ [])
end
...
```### Usage with Plug
If you have a `Plug` application, assuming you already set up routingm you can call `JSONAPIPlug.render/4` in your
pipeline to generate a `JSONAPI.Document` with your data for the client.```elixir
JSONAPIPlug.render(conn, post)
|> Jason.encode!()
```Render returns a `JSONAPI.Document`, that is serializable to JSON via `Jason`.
## Contributing
- This project was born as a fork of the [jsonapi][jsonapi-fork]
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[changelog]: https://hexdocs.pm/jsonapi_plug/changelog.html
[json:api-1.0]: https://jsonapi.org/format/1.0/
[json:api-1.1]: https://jsonapi.org/format/1.1/
[json:api]: https://jsonapi.org
[jsonapi-fork]: https://github.com/beam-community/jsonapi
[jsonapi_plug-hexdocs]: https://hexdocs.pm/jsonapi_plug
[upgrade]: https://hexdocs.pm/jsonapi_plug/upgrading.html