Skip to content

Repository files navigation

restpack_serializer

Build StatusCode ClimateDependency StatusGem VersionCoverage Status

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.

Live Demo of RestPack Serializer


NOTE: This gem needs maintainers: #128


Getting Started

For rails projects:

After adding the gem restpack_serializer to your Gemfile, add this code to config/initializers/restpack_serializer.rb:

Dir[Rails.root.join('app/serializers/**/*.rb')].eachdo |path|
requirepathend

Serialization

Let's say we have an Album model:

classAlbum < ActiveRecord::Baseattr_accessible:title,:year,:artistbelongs_to:artisthas_many:songsend

restpack_serializer allows us to define a corresponding serializer:

classAlbumSerializerincludeRestPack::Serializerattributes:id,:title,:year,:artist_id,:hrefend

AlbumSerializer.as_json(album) produces:

{"id": "1","title": "Kid A","year": 2000,"artist_id": 1,"href": "/albums/1"}

as_json accepts an optional context hash parameter which can be used by your Serializers to customize their output:

classAlbumSerializerincludeRestPack::Serializerattributes:id,:title,:year,:artist_id,:extrasoptional:scorecan_include:artists,:songscan_filter_by:yeardefextrasif@context[:admin?]{markup_percent: 95}endendend
AlbumSerializer.as_json(album,{admin?: true})

All attributes are serialized by default. If you'd like to skip an attribute, you can pass an option in the @context as follows:

AlbumSerializer.as_json(album,{include_title?: false})

You can also define optional attributes which aren't included by default. To include:

AlbumSerializer.as_json(album,{include_score?: true})

Exposing an API

The AlbumSerializer provides page and resource methods which provide paged collection and singular resource GET endpoints.

classAlbumsController < ApplicationControllerdefindexrenderjson: AlbumSerializer.page(params)enddefshowrenderjson: AlbumSerializer.resource(params)endend

These endpoint will live at URLs such as /albums and /albums/142857:

The AlbumSerializer also provides a single method which will return a serialized resource similar to as_json above.

page, resource and single methods take an optional scope argument allowing us to enforce arbitrary constraints:

AlbumSerializer.page(params,Albums.where("year < 1950"))

In addition to scope, all three methods also accept an optional context hash:

AlbumSerializer.page(params,Albums.where("year < 1950"),{admin?: true})

Other features:

Paging

Collections are paged by default. page and page_size parameters are available:

Paging details are included in a meta attribute:

http://restpack-serializer-sample.herokuapp.com/api/v1/songs.json?page=2&page_size=3 yields:

{"songs": [{"id": "4","title": "How to Dissapear Completely","href": "/songs/4","links": {"artist": "1","album": "1"}},{"id": "5","title": "Treefingers","href": "/songs/5","links": {"artist": "1","album": "1"}},{"id": "6","title": "Optimistic","href": "/songs/6","links": {"artist": "1","album": "1"}}],"meta": {"songs": {"page": 2,"page_size": 3,"count": 42,"include": [],"page_count": 14,"previous_page": 1,"next_page": 3,"first_href": "/songs?page_size=3","previous_href": "/songs?page_size=3","next_href": "/songs?page=3&page_size=3","last_href": "/songs?page=14&page_size=3"}},"links": {"songs.artist": {"href": "/artists/{songs.artist}","type": "artists"},"songs.album": {"href": "/albums/{songs.album}","type": "albums"}}}

URL Templates to related data are included in the links element. These can be used to construct URLs such as:

  • /artists/1
  • /albums/1

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:

classAlbumSerializerincludeRestPack::Serializerattributes:id,:title,:year,:artist_id,:hrefcan_include:songs,:artistsend

In this example, we are allowing related songs and artists to be included in API responses. Side-loads can be specifed by using the include parameter:

No side-loads

Side-load related Artists

which yields:

{"albums": [{"id": "1","title": "Kid A","year": 2000,"href": "/albums/1","links": {"artist": "1"}},{"id": "2","title": "Amnesiac","year": 2001,"href": "/albums/2","links": {"artist": "1"}},{"id": "3","title": "Murder Ballads","year": 1996,"href": "/albums/3","links": {"artist": "2"}},{"id": "4","title": "Curtains","year": 2005,"href": "/albums/4","links": {"artist": "3"}}],"meta": {"albums": {"page": 1,"page_size": 10,"count": 4,"include": ["artists"],"page_count": 1,"previous_page": null,"next_page": null,"first_href": '/albums',"previous_href": null,"next_href": null,"last_href": '/albums'}},"links": {"albums.songs": {"href": "/songs?album_id={albums.id}","type": "songs"},"albums.artist": {"href": "/artists/{albums.artist}","type": "artists"},"artists.albums": {"href": "/albums?artist_id={artists.id}","type": "albums"},"artists.songs": {"href": "/songs?artist_id={artists.id}","type": "songs"}},"linked": {"artists": [{"id": "1","name": "Radiohead","website": "http://radiohead.com/","href": "/artists/1"},{"id": "2","name": "Nick Cave & The Bad Seeds","website": "http://www.nickcave.com/","href": "/artists/2"},{"id": "3","name": "John Frusciante","website": "http://johnfrusciante.com/","href": "/artists/3"}]}}

Side-load related Songs

An album :has_many songs, so the side-loaded songs are paged. The meta.songs includes previous_href and next_href which point to the previous and next page of this side-loaded data. These URLs take the form:

Side-load related Artists and Songs

Filtering

Simple filtering based on primary and foreign keys is supported by default:

By primary key:

By foreign key:

Custom filters:

Custom filters can be defined with the can_filter_by option:

classAccountincludeRestPack::Serializerattributes:id,:application_id,:created_by,:name,:hrefcan_filter_by:application_idend

Side-loading is available when filtering:

Sorting

Sorting attributes can be defined with the can_sort_by option:

classAccountincludeRestPack::Serializerattributes:id,:application_id,:created_by,:name,:hrefcan_sort_by:id,:nameend

Running Tests

bundlerake spec

About

Model serialization, paging, side-loading and filtering

Resources

Stars

175 stars

Watchers

4 watching

Forks

Releases

Packages

Used by

Contributors

Languages