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.
Railtie
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
Controllers
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
private
def nagare_context
@nagare_context ||= Nagare::Context.new({
current_user: current_user,
})
end
end
A regular controller looks like this:
class AdminOrdersController < ApplicationController
def index
render({
json: orders,
serializers: { collection: AdminOrdersSerializer, item: AdminOrderSerializer },
context: {
href: orders_url,
},
})
end
def show
render({
json: order,
serializers: { item: AdminOrderSerializer },
context: {
href: order_url(order),
},
})
end
end
The collection key is required if you have a collection. I found this to be a good pattern when working on Artifact.
Serializers
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
collection.count
end
end
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
object.items.count
end
end
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.