Test rails-api application which implements JSON-API spec using Roar gem.
$ git clone https://github.com/vdmgolub/json_api_roar.git
$ cd json_api_roar
$ bundle
$ bin/rake db:migrate
$ bin/rake db:seed
$ bin/rails s
$ bin/rake
GET /posts
{
"links": {
"posts.author": {
"href": "http://example.com/authors/{posts.author}",
"type": "authors"
}
},
"posts": [{
"id": 1,
"text": "some text",
"created_at": "2014-08-03T13:08:58Z",
"links": {
"author": 1
}
}, {
"id": 2,
"text": "some text",
"created_at": "2014-08-03T13:08:58Z",
"links": {
"author": 2
}
}],
"linked": {
"authors": [{
"id": 1,
"name": "Jay"
},{
"id": 2,
"name": "Silent Bob"
}]
}
}
GET /posts/:id
{
"links": {
"posts.author": {
"href": "http://example.com/authors/{posts.author}",
"type": "authors"
}
},
"posts": {
"id": 1,
"text": "some text",
"created_at": "2014-08-03T13:08:58Z",
"links": {
"author": 1
}
},
"linked": {
"authors": [{
"id": 1,
"name": "Jay"
}]
}
}
GET /authors
{
"authors": [{
"id": 1,
"name": "Jay"
},{
"id": 2,
"name": "Silent Bob"
}]
}
GET /authors/:id
{
"authors": {
"id": 1,
"name": "Jay"
}
}
GET /authors/:author_id/posts
{
"posts": [{
"id": 1,
"text": "some text",
"created_at": "2014-08-03T13:08:58Z"
}, {
"id": 3,
"text": "some text",
"created_at": "2014-08-03T13:08:58Z"
}]
}
-
GET /authors
is a basic JSON-API endpoint without anylinks
andlinked
sections. It's an easy one to implement usingRoar
, see app/representers/authors_representer. -
The complexity starts to grow when
links
and compoundlinked
objects need to be returned. Implementation is here app/representers/posts_representer. Now we need to create a 'wrapper' resource object which will include target objects, links and all related compound objects. Compound object should be collected from all target objects and filtered from duplicates. SeePostExtendedRepresenter
wherelinks
attribute is added with related author id. -
Boilerplate grows more when the same resource is returned from different endpoints like
GET /posts
andGET /authors/:author_id/posts
. When author's posts are returned there is no need to include the author. NowAuthorPostsRepresenter
is implemented. -
The result is that for one resource there are several representers according to endpoint. Plus it is time consuming to iterate through all related objects to gather them in
linked
section.