Reshaping objects for API requests and responses

ecto
api
phoenix

#1

I need to reshape my ecto models when responding to API requests, and I also need to create request objects that I want to bind to when I get a API request.

So my API responses in Ruby would look like:

class ApiResponse
attr_accessor :success, :errors
def initialize(success, errors)
@success = success
@errors = errors
end

And then say for my /api/users response I would have a users collection also so:

response.success = true
response.errors = []
response.users = users

render json: response

In phoenix/elixir, would I just be creating a module with a struct for each response then to mimic the above?


#2

In general response shape is handled by a json view, which just has simple functions that return simple maps. https://www.rokkincat.com/blog/2015/03/17/json-views-in-phoenix


#3

Just call json function in your controller’s action:

defmodule YouApiController do
  def index(conn, _) do
    # get your users here
    conn
    |> json(%{success: true, errors: [], users: users})
  end
end

Of course, json view should be preferred :slight_smile:


#4

I prefer having the json inline, why would I want it in a view? :slight_smile:


#5

It’s much easier to test when your json response get complex.


#6

The other way of looking at it is as a “Content-Template” - the term “view” is heavily influenced by the pre-dominance of a Content-Type of text/html in many HTTP requests/responses.

When the required Content-Type is application/json you simply select a JSON template to render your Elixir data into the appropriate media-type representation.

The underlying idea being is that the same data (“resource state”) can have representations across a whole range of different media-types.