Rethinking Rails API Serialization - Part 3

Posted on 23 Mar 2016 by Eric Oestrich

Part 3 will wrap up this series and show off a full example of how Nagare can be used.

Name fun fact: Nagare (流れ) is Japanese for a stream or flow.


The railtie included with Nagare changes the default _render_with_renderer_json method on controllers, similar to ActiveModel::Serializers. You can see a full version of it on github.

A Full Example


We start by defining a context that lets the context have a current user. Anything else a serializer might want can be added here.

class ApplicationController < ActionController::Base

  def nagare_context
    @nagare_context ||={
      current_user: current_user,

A regular controller looks like this:

class AdminOrdersController < ApplicationController
  def index
      json: orders,
      serializers: { collection: AdminOrdersSerializer, item: AdminOrderSerializer },
      context: {
        href: orders_url,

  def show
      json: order,
      serializers: { item: AdminOrderSerializer },
      context: {
        href: order_url(order),

The collection key is required if you have a collection. I found this to be a good pattern when working on Artifact.


The serializers are pretty simple. The serializers can customize which attributes will be output. In Artifact I extend these with a custom DSL for [Collection+JSON][cjson] to include links, queries, and templates.

class AdminOrdersSerializer < Nagare::Collection
  # This is the key that will contain all of the serialized items.
  key "orders"

  # You can also have extra attributes on the collection
  attributes :count

  def count

Serializers have several ways of obtaining attributes. It can be a method on the serializer itself, the object, or from the context.

class AdminOrderSerializer < Nagare::Item
  # email is a method off of the order
  # item_count is a method we define
  # href comes from the passed in context
  attributes :email, :item_count, :href

  def item_count

attributes defines a method per attribute that will try the object or context for the attribute value. Otherwise you can simply define your own method to use.

Wrapping Up

This brings the Rethinking Rails API Serialization series to a close. I hope you found something useful. Please read over the source for Nagare. I welcome issues or pull requests.

Rethinking Rails API Serializations Series

comments powered by Disqus
Creative Commons License
This site's content is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License unless otherwise specified. Code on this site is licensed under the MIT License unless otherwise specified.