restpack_serializer
Model serialization, paging, side-loading and filtering
restpack_serializer allows you to quickly provide a set of RESTful endpoints for your application. It is an implementation of the emerging JSON API standard.
Serialization
Let's say we have an Album model:
class Album < ActiveRecord::Base
attr_accessible :title, :year, :artist
belongs_to :artist
has_many :songs
end
restpack_serializer allows us to define a corresponding serializer:
class AlbumSerializer
include RestPack::Serializer
attributes :id, :title, :year, :artist_id, :href
end
AlbumSerializer.as_json(album) produces:
{
"id": "1",
"title": "Kid A",
"year": 2000,
"artist_id": 1,
"href": "/albums/1.json"
}
Exposing an API
The AlbumSerializer provides page and resource methods which provide paged collection and singular resource GET endpoints.
class AlbumsController < ApplicationController
def index
render json: AlbumSerializer.page(params)
end
def show
render json: AlbumSerializer.resource(params)
end
end
These endpoint will live at URLs such as /albums.json and /albums/142857.json:
- http://restpack-serializer-sample.herokuapp.com/albums.json
- http://restpack-serializer-sample.herokuapp.com/albums/4.json
Both page and resource methods take an optional scope argument allowing us to enforce arbitrary constraints:
AlbumSerializer.page(params, Albums.where("year < 1950"))
Paging
Collections are paged by default. page and page_size parameters are available:
- http://restpack-serializer-sample.herokuapp.com/songs.json?page=2
- http://restpack-serializer-sample.herokuapp.com/songs.json?page=2&page_size=3
Paging details are included in a meta attribute:
http://restpack-serializer-sample.herokuapp.com/songs.json?page=2&page_size=3 yields:
{
"songs": [
{
"id": "4",
"title": "How to Dissapear Completely",
"href": "/songs/4.json",
"links": {
"artist": "1",
"album": "1"
}
},
{
"id": "5",
"title": "Treefingers",
"href": "/songs/5.json",
"links": {
"artist": "1",
"album": "1"
}
},
{
"id": "6",
"title": "Optimistic",
"href": "/songs/6.json",
"links": {
"artist": "1",
"album": "1"
}
}
],
"meta": {
"songs": {
"page": 2,
"page_size": 3,
"count": 42,
"includes": [],
"page_count": 14,
"previous_page": 1,
"next_page": 3,
"previous_href": "/api/v1/songs.json?page_size=3",
"next_href": "/api/v1/songs.json?page=3&page_size=3"
}
},
"links": {
"songs.artist": {
"href": "/artists/{songs.artist}.json",
"type": "artists"
},
"songs.album": {
"href": "/albums/{songs.album}.json",
"type": "albums"
}
}
}
URL Templates to related data are included in the links element. These can be used to construct URLs such as:
- /artists/1.json
- /albums/1.json
Side-loading
Side-loading allows related resources to be optionally included in a single API response. Valid side-loads can be defined in Serializers by using can_include as follows:
class AlbumSerializer
include RestPack::Serializer
attributes :id, :title, :year, :artist_id, :href
can_include :songs, :artists
end
In this example, we are allowing related songs and artists to be included in API responses. Side-loads can be specifed by using the includes parameter:
No side-loads
Side-load related Artists
which yields:
{
"albums": [
{
"id": "1",
"title": "Kid A",
"year": 2000,
"href": "/albums/1.json",
"links": {
"artist": "1"
}
},
{
"id": "2",
"title": "Amnesiac",
"year": 2001,
"href": "/albums/2.json",
"links": {
"artist": "1"
}
},
{
"id": "3",
"title": "Murder Ballads",
"year": 1996,
"href": "/albums/3.json",
"links": {
"artist": "2"
}
},
{
"id": "4",
"title": "Curtains",
"year": 2005,
"href": "/albums/4.json",
"links": {
"artist": "3"
}
}
],
"meta": {
"albums": {
"page": 1,
"page_size": 10,
"count": 4,
"includes": [
"artists"
],
"page_count": 1,
"previous_page": null,
"next_page": null,
"previous_href": null,
"next_href": null
}
},
"links": {
"albums.songs": {
"href": "/songs.json?album_id={albums.id}",
"type": "songs"
},
"albums.artist": {
"href": "/artists/{albums.artist}.json",
"type": "artists"
},
"artists.albums": {
"href": "/albums.json?artist_id={artists.id}",
"type": "albums"
},
"artists.songs": {
"href": "/songs.json?artist_id={artists.id}",
"type": "songs"
}
},
"artists": [
{
"id": "1",
"name": "Radiohead",
"website": "http://radiohead.com/",
"href": "/artists/1.json"
},
{
"id": "2",
"name": "Nick Cave & The Bad Seeds",
"website": "http://www.nickcave.com/",
"href": "/artists/2.json"
},
{
"id": "3",
"name": "John Frusciante",
"website": "http://johnfrusciante.com/",
"href": "/artists/3.json"
}
]
}
Side-load related Songs
An album :has_many songs, so the side-loads are paged. We'll be soon adding URLs to the response meta data which will point to the next page of side-loaded data. These URLs will be something like:
Side-load related Artists and Songs
Filtering
Simple filtering based on primary and foreign keys is possible:
By primary key:
- http://restpack-serializer-sample.herokuapp.com/albums.json?id=1
- http://restpack-serializer-sample.herokuapp.com/albums.json?ids=1,2,4
By foreign key:
- http://restpack-serializer-sample.herokuapp.com/albums.json?artist_id=1
- http://restpack-serializer-sample.herokuapp.com/albums.json?artist_ids=2,3
Side-loading is available when filtering:




