AMS adapters in Rails 5 are important for building a wonderful RESTful API because they provide hypermedia controls and links in the API response. The JSON API adapter in particular generates responses that follow the JSON API specification by including links, relationships, pagination metadata, and embedded resources. Adapters allow Rails to render different representation formats like JSON API, customize the API structure, and improve the developer experience of the API through conventions like hypermedia controls and links. However, there is still work to be done on adapters, like improving deserialization, documentation, and better supporting JSON API conventions fully.
11. ResourcesResources
Any information that can be named can be a resource: a document
or image, a temporal service (e.g. "today's weather in Los Angeles"), a
collection of other resources, a non-virtual object (e.g. a person), and
so on. In other words, any concept that might be the target of an
author's hypertext reference must fit within the definition of a
resource.
Roy T. Fielding
27. #app/controllers
class PostsController < ApplicationController
def index
@posts = Post.all
render json: @posts
end
end
#app/serializers
class PostSerializer < ActiveModel::Serializer
attributes :id, :name, :date
has_many :comments
end
28. module ActionController
module Serialization
extend ActiveSupport::Concern
include ActionController::Renderers
...
[:_render_option_json, :_render_with_renderer_json].each do |renderer_method|
define_method renderer_method do |resource, options|
options.fetch(:context) { options[:context] = request }
serializable_resource = get_serializer(resource, options)
super(serializable_resource, options)
end
end
...
end
end
38. module ActiveModel
class Serializer
class Adapter
....
def self.create(resource, options = {})
override = options.delete(:adapter)
klass = override ? adapter_class(override) : ActiveModel::Serializer.adapter
klass.new(resource, options)
end
...
end
end
end
40. module Example
class UsefulAdapter < ActiveModel::Serializer::Adapter
end
end
# Automatically register adapters when subclassing
def self.inherited(subclass)
ActiveModel::Serializer::Adapter.register(subclass.to_s.demodulize, subclass)
end
First optionFirst option
50. module ActiveModel
class Serializer
class Adapter
class JsonApi < Adapter
...
def add_links(options)
links = @hash.fetch(:links) { {} }
resources = serializer.instance_variable_get(:@resource)
if is_paginated?(resources)
@hash[:links] = add_pagination_links(links, resources, options)
end
end
def add_pagination_links(links, resources, options)
pagination_links = JsonApi::PaginationLinks.new(resources, options[:context])
.serializable_hash(options)
links.update(pagination_links)
end
def is_paginated?(resource)
resource.respond_to?(:current_page) &&
resource.respond_to?(:total_pages) &&
resource.respond_to?(:size)
end
...
end
end
end
end
56. Here are the links!Here are the links!
"data": [{
"type": "posts",
"id": "1",
"attributes": { "title": "JSON API paints my bikeshed!" },
"relationships": {
"author": {
"links": {
"self": "http://example.com/posts/1/relationships/author",
"related": "http://example.com/posts/1/author"
},
"data": { "type": "people", "id": "9" }
},
"comments": {
"links": {
"self": "http://example.com/posts/1/relationships/comments",
"related": "http://example.com/posts/1/comments"
},
"data": [{ "type": "comments", "id": "5" }]
}
},
"links": { "self": "http://example.com/posts/1" }
}],
57. BuuutBuuut there is stillthere is still
a lot of work to do...a lot of work to do...
58. Deserialization (for both JSON-API and JSON)
Documentation
A better AC/Serializers integration API
Provide better naming for JSON Adapter
Add support to all conventions on JSON-API
Bring Filter back from older version
Russian Doll Cache (use #fetch_multi)
Start handle nested associations
59. ams =ams = Array.Array.newnew
amsams <<<< hyperlinkshyperlinks
ams << media-type flexibilityams << media-type flexibility
ams << API more attractiveams << API more attractive
ams << API more explorableams << API more explorable