# Creating JSON-API in Elixir-Phoenix with ease using ja_serializer.

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 configure `ja_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 with `Repo`.
- Next, we are going to add `Post` model along with `Blog` 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 run `MyBlogApi.Blog.list_posts`. This is going to return all `Posts`. 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"}` in `mix.exs` and run `mix deps.get`.
- Now we need to configure our app to use `ja_serializer`. We need to add configuration in our app to make it use `json-api` specification headers.
- We are going to install a plugin called `poison` to encode requests for our new `json-api` mime type. (To install `poison` add `poison` in `mix.exs` and run `mix deps.get`).
- We will do this by adding a line below our app `config` in `config/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 only `json` type. Add `json-api` as well in it. Update the line as below
```exs
 render_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
      ```

### DEMO:
- Now that we have configured `ja_serializer`, we will now create a `Post#index` endpoint to see `json-api` response.
- Go to `router.ex` add `resources /posts, PostController, only: [:index]`
- Create post controller in `my_blog_api_web/controllers/post_controller.ex`.
- Add an index `action`.
```ex
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 for `post` to render json and add the following code.
```ex
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 hit `posts` endpoint i.e `localhost:4000/posts` you can see the response in `json-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👇 
- [Installing CORS in Elixir-Phoenix application](https://abulasar.com/installing-cors-in-elixir-phoenix-application)

### References:
- [Ja-Serializer](https://github.com/vt-elixir/ja_serializer)


