Today, most of the Web application uses Modern Frontend frameworks like React, Angular, Ember, etc. These frameworks use the JSON API to interact with some back-end. JSON-API is the preferred specification for building APIs. This post will help you in creating JSON-API
using ja_serializer
(an Elixir library) for an Elixir-Phoenix app. We are going to create a simple Blog
(everyone's favorite example ๐ ) application. This application will generate JSON-API, which will be accessible for SPA's to use.
I'll divide this post into 3 parts for the sake of simplicity:
- Creating the new app, along with that I'll add one resource(Post model with Context).
- Configuring
ja_serializer
(Here we will configureja_serializer
). - Final Demo (We'll see
ja_serializer
into action).
Creating a new Phoenix application:
- First, we are going to create a new Phoenix application with following command in your terminal.
mix phx.new --no-webpack --no-html my_blog_api
- After the project is generated run
cd my_blog_api
. - Run
mix ecto.create
. This will generate database along withRepo
. - Next, we are going to add
Post
model along withBlog
context. This can be achieved by following command.mix phx.gen.context Blog Post posts title:string body:text //This will create `Post` model along with `Blog` context and 5 main `CRUD` operations methods.
- You can test this by running
iex -S mix phx.server
and runMyBlogApi.Blog.list_posts
. This is going to return allPosts
. In our case its a fresh app. So, try creating few records and test this function later :) . - Now, we are ready with one resource, we can hop to next level.
Configuring ja_serializer
:
- To install we are going to add
{:ja_serializer, "~> 0.12.0"}
inmix.exs
and runmix deps.get
. - Now we need to configure our app to use
ja_serializer
. We need to add configuration in our app to make it usejson-api
specification headers. - We are going to install a plugin called
poison
to encode requests for our newjson-api
mime type. (To installpoison
addpoison
inmix.exs
and runmix deps.get
). - We will do this by adding a line below our app
config
inconfig/config.exs
.config :mime, :types, %{ "application/vnd.api+json" => ["json-api"] } config :phoenix, :format_encoders, "json-api": Poison
Also update the error type in
ErrorView
in the same file. It has an array with onlyjson
type. Addjson-api
as well in it. Update the line as belowrender_errors: [view: MyBlogApiWeb.ErrorView, accepts: ~w(json json-api)],
Now we need to rebuild the plugin dependency by running the following command.
mix deps.clean mime --build
Next, we have to do some setup to make our router to use
ja_serializer
:- To deserialize the request coming in we will add
plug JaSerializer.ContentTypeNegotiation
- Add plug
jaserilaizer deserializer
to convert bobcase property to underscore property.plug JaSerializer.Deserializer
- In router.ex
pipeline :api do plug :accepts, ["json", "json-api"] plug JaSerializer.ContentTypeNegotiation plug JaSerializer.Deserializer end
- To deserialize the request coming in we will add
DEMO:
- Now that we have configured
ja_serializer
, we will now create aPost#index
endpoint to seejson-api
response. - Go to
router.ex
addresources /posts, PostController, only: [:index]
- Create post controller in
my_blog_api_web/controllers/post_controller.ex
. Add an index
action
.defmodule MyBlogApiWeb.PostController do use MyBlogApiWeb, :controller alias MyBlogApi.Blog def index(conn, _params) do posts = Blog.list_posts() render(conn, "index.json-api", data: posts) end end
Create a
my_blog_api_web/views/post_view.ex
file forpost
to render json and add the following code.defmodule MyBlogApiWeb.PostView do use MyBlogApiWeb, :view use JaSerializer.PhoenixView attributes [:title, :body] end
- In
attributes
macro, we can specify the fields we want to send in response. - Now, start your server and open
postman
and hitposts
endpoint i.elocalhost:4000/posts
you can see the response injson-api
format.
I hope you like this post. If you any questions please add the comment below.๐
Note:
If you face an error related to CORS
while integrating this API into the frontend- framework follow this blog๐