SlideShare a Scribd company logo
1 of 62
Download to read offline
Why AMS Adapters, in Rails 5,
are so important to a
wonderful RESTful API
{
"data": {
"type": "Developer",
"id": "Tiago Freire",
"attributes": {
"nickname" : "Kuruma",
"background_knowledge": [ "C", "C++", "C#", "Java"],
"current_language:": "Ruby",
"interest": "Rust"
},
"relationships": {
"jobs": {
"data": { "type": "Software Boutique", "id": "Codeminer42" },
"links": {
"related": {
"href": "http://www.codeminer42.com"
}
}
},
"consultancy": {
"data": { "type": "Host and Cloud services", "id": "Locaweb" },
"links": {
"related": {
"href": "http://www.locaweb.com.br"
}
}
}
}
}
}
{
"data": {
"type": "Developer",
"id": "Bruno Bacarini",
"attributes": {
"nickname" : "bacarini",
"background_knowledge": ["Java"],
"current_language:": "Ruby"
},
"relationships": {
"jobs": [
{ "data": {
"type": "Host and Cloud services",
"id": "Locaweb"
},
"links": {
"related": {
"href": "http://www.locaweb.com.br"
}
}
},{
"data": {
"type": "e-recruitment",
"id": "VAGAS.com"
},
"links": {
"related": {
"href": "http://www.vagas.com.br"
}
}
}]
}
}
}
Developer
Experience
JSON API
Rails 5Rails 5
REST
API
AMS
Hypermedia
Adapters
Patterns
Documentation
GoodGood
ExperienceExperience
MotivationMotivation
DeveloperDeveloper
ExperienceExperience
REST
Representational State Transfer
ProtocolProtocol
HTTPHTTP
The Hypertext Transfer Protocol (HTTP) is a stateless
application-level protocol for distributed, collaborative,
hypertext information systems.
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
HTTP verbsHTTP verbs
[C] POST
[R] GET
[U] PUT / PATCH
[D] DELETE
Hypermedia controlHypermedia control
Machines can follow links when they understand the data format and
relationship types.
Roy T. Fielding
So, where are the
links?
Media TypeMedia Type
Content-typeContent-type
andand
AcceptAccept
Collection+JSON
HAL
JSON-LD
SIREN
JSON-API
...
APIsAPIs
RAILS-API
RAILS 5
rails new appname --apirails new appname --api
ActiveModel::
Serializer
#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
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
Adapters
Steve KlabnikSteve Klabnik
Yehuda KatzYehuda Katz
JsonAPIJsonAPI
==
anti-bikesheddinganti-bikeshedding
weaponweapon
How to use adaptersHow to use adapters
(Specially JsonAPI)?(Specially JsonAPI)?
#controller/action
render json: @posts, adapter: :json_api
#OR
#config/initializer
ActiveModel::Serializer.config.adapter = :json_api
Accept: application/vnd.example[.version].param[+json]
curl -v -H 'Accept:application/vnd.example.v1+json' localhost:3000
ActiveModel::Serializer::Adapter.register(:json_v1, Json)
ActiveModel::Serializer::Adapter.register(:json_v2, JsonApi)
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
Creating my ownCreating my own
adapteradapter
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
class MyAdapter; end
ActiveModel::Serializer::Adapter.register(:special_adapter, MyAdapter)
Second optionSecond option
Relationships
Included
Pagination
Meta
#app/serializers
class PostSerializer < ActiveModel::Serializer
attributes :id, :title
has_many :comments
has_one :author
end
"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" }
}],
class PostsController < ApplicationController
def show
@post = Post.find params[:id]
render json: @post, adapter: :json_api, include: ['comments', 'author']
end
end
"included": [{
"type": "people", "id": "9",
"attributes": {
"first-name": "Dan",
"last-name": "Gebhardt",
"twitter": "dgeb"
},
"links": { "self": "http://example.com/people/9" }
}, {
"type": "comments", "id": "5",
"attributes": { "body": "First!" },
"links": { "self": "http://example.com/comments/5" }
}],
Nested AssociationsNested Associations
(JsonAPI adapter)
class PostsController < ApplicationController
def show
@post = Post.find params[:id]
render json: @post, adapter: :json_api, include: [author: [:bio]]
end
end
class PostSerializer < ActiveModel::Serializer
attributes :id, :name
has_many :author
end
class AuthorSerializer < ActiveModel::Serializer
attributes :id, :name
has_one :bio
end
class BioSerializer < ActiveModel::Serializer
attributes :id, :title
belongs_to :author
end
"included": [
{
"id": "1",
"type": "author",
"attributes": {
"name": "bruno"
},
"relationships": {
"bio": {
"data": [
{
"id": "1",
"type": "bio"
}
]
}
}
},
{
"id": "1",
"type": "bio",
"attributes": {
"title": "foobar"
}
},
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
"links": {
"self": "http://example.com/posts?page%5Bnumber%5D=3&page%5Bsize%5D=1",
"first": "http://example.com/posts?page%5Bnumber%5D=1&page%5Bsize%5D=1",
"prev": "http://example.com/posts?page%5Bnumber%5D=2&page%5Bsize%5D=1",
"next": "http://example.com/posts?page%5Bnumber%5D=4&page%5Bsize%5D=1",
"last": "http://example.com/posts?page%5Bnumber%5D=10&page%5Bsize%5D=1"
}
class PostsController < ApplicationController
def show
@post = Post.find params[:id]
render json: @post, adapter: :json_api, meta: { "total-pages" => 10 }
end
end
"meta": {
"total-pages": 10
}
{
"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" }
}],
"included": [{
"type": "people", "id": "9",
"attributes": {
"first-name": "Dan",
"last-name": "Gebhardt",
"twitter": "dgeb"
},
"links": { "self": "http://example.com/people/9" }
}, {
"type": "comments", "id": "5",
"attributes": { "body": "First!" },
"links": { "self": "http://example.com/comments/5" }
}],
"links": {
"self": "http://example.com/posts?page%5Bnumber%5D=3&page%5Bsize%5D=1",
"first": "http://example.com/posts?page%5Bnumber%5D=1&page%5Bsize%5D=1",
"prev": "http://example.com/posts?page%5Bnumber%5D=2&page%5Bsize%5D=1",
"next": "http://example.com/posts?page%5Bnumber%5D=4&page%5Bsize%5D=1",
"last": "http://example.com/posts?page%5Bnumber%5D=10&page%5Bsize%5D=1"
},
"meta": {
"total-pages": 10
}
}
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" }
}],
BuuutBuuut there is stillthere is still
a lot of work to do...a lot of work to do...
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
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
GoodGood
ExperienceExperience
Thank you allThank you all

More Related Content

What's hot

Specification-Driven Development of REST APIs by Alexander Zinchuk
Specification-Driven Development of REST APIs by Alexander Zinchuk   Specification-Driven Development of REST APIs by Alexander Zinchuk
Specification-Driven Development of REST APIs by Alexander Zinchuk OdessaJS Conf
 
BruJUG Brussels GraphQL when RESR API is to less - lessons learned
BruJUG Brussels GraphQL when RESR API is to less - lessons learnedBruJUG Brussels GraphQL when RESR API is to less - lessons learned
BruJUG Brussels GraphQL when RESR API is to less - lessons learnedMarcinStachniuk
 
Securing WordPress
Securing WordPressSecuring WordPress
Securing WordPressShawn Hooper
 
Building sustainable RESTFul services
Building sustainable RESTFul servicesBuilding sustainable RESTFul services
Building sustainable RESTFul servicesOrtus Solutions, Corp
 
jQuery from the very beginning
jQuery from the very beginningjQuery from the very beginning
jQuery from the very beginningAnis Ahmad
 
Together Cheerfully to Walk with Hypermedia
Together Cheerfully to Walk with HypermediaTogether Cheerfully to Walk with Hypermedia
Together Cheerfully to Walk with HypermediaVladimir Tsukur
 
Agile Testing Days 2018 - API Fundamentals - postman collection
Agile Testing Days 2018 - API Fundamentals - postman collectionAgile Testing Days 2018 - API Fundamentals - postman collection
Agile Testing Days 2018 - API Fundamentals - postman collectionJoEllen Carter
 
APIdays Helsinki 2019 - Specification-Driven Development of REST APIs with Al...
APIdays Helsinki 2019 - Specification-Driven Development of REST APIs with Al...APIdays Helsinki 2019 - Specification-Driven Development of REST APIs with Al...
APIdays Helsinki 2019 - Specification-Driven Development of REST APIs with Al...apidays
 
「リモートペアプロでマントルを突き抜けろ!」AWS Cloud9でリモートペアプロ&楽々サーバーレス開発
「リモートペアプロでマントルを突き抜けろ!」AWS Cloud9でリモートペアプロ&楽々サーバーレス開発「リモートペアプロでマントルを突き抜けろ!」AWS Cloud9でリモートペアプロ&楽々サーバーレス開発
「リモートペアプロでマントルを突き抜けろ!」AWS Cloud9でリモートペアプロ&楽々サーバーレス開発Atsushi Fukui
 
Intro to @viewport & other new Responsive Web Design CSS features
Intro to @viewport & other new Responsive Web Design CSS featuresIntro to @viewport & other new Responsive Web Design CSS features
Intro to @viewport & other new Responsive Web Design CSS featuresAndreas Bovens
 
What’s Your Problem?
What’s Your Problem?What’s Your Problem?
What’s Your Problem?Nordic APIs
 
E2 appspresso hands on lab
E2 appspresso hands on labE2 appspresso hands on lab
E2 appspresso hands on labNAVER D2
 
Building Beautiful REST APIs in ASP.NET Core
Building Beautiful REST APIs in ASP.NET CoreBuilding Beautiful REST APIs in ASP.NET Core
Building Beautiful REST APIs in ASP.NET CoreStormpath
 
Beautiful REST+JSON APIs with Ion
Beautiful REST+JSON APIs with IonBeautiful REST+JSON APIs with Ion
Beautiful REST+JSON APIs with IonStormpath
 
RESTFUL SERVICES MADE EASY: THE EVE REST API FRAMEWORK - Nicola Iarocci - Co...
RESTFUL SERVICES MADE EASY: THE EVE REST API FRAMEWORK -  Nicola Iarocci - Co...RESTFUL SERVICES MADE EASY: THE EVE REST API FRAMEWORK -  Nicola Iarocci - Co...
RESTFUL SERVICES MADE EASY: THE EVE REST API FRAMEWORK - Nicola Iarocci - Co...Codemotion
 

What's hot (20)

Specification-Driven Development of REST APIs by Alexander Zinchuk
Specification-Driven Development of REST APIs by Alexander Zinchuk   Specification-Driven Development of REST APIs by Alexander Zinchuk
Specification-Driven Development of REST APIs by Alexander Zinchuk
 
Advanced Json
Advanced JsonAdvanced Json
Advanced Json
 
BruJUG Brussels GraphQL when RESR API is to less - lessons learned
BruJUG Brussels GraphQL when RESR API is to less - lessons learnedBruJUG Brussels GraphQL when RESR API is to less - lessons learned
BruJUG Brussels GraphQL when RESR API is to less - lessons learned
 
Securing WordPress
Securing WordPressSecuring WordPress
Securing WordPress
 
Building sustainable RESTFul services
Building sustainable RESTFul servicesBuilding sustainable RESTFul services
Building sustainable RESTFul services
 
jQuery from the very beginning
jQuery from the very beginningjQuery from the very beginning
jQuery from the very beginning
 
Together Cheerfully to Walk with Hypermedia
Together Cheerfully to Walk with HypermediaTogether Cheerfully to Walk with Hypermedia
Together Cheerfully to Walk with Hypermedia
 
What's Your Problem?
What's Your Problem?What's Your Problem?
What's Your Problem?
 
Agile Testing Days 2018 - API Fundamentals - postman collection
Agile Testing Days 2018 - API Fundamentals - postman collectionAgile Testing Days 2018 - API Fundamentals - postman collection
Agile Testing Days 2018 - API Fundamentals - postman collection
 
HTML 5 & CSS 3
HTML 5 & CSS 3HTML 5 & CSS 3
HTML 5 & CSS 3
 
APIdays Helsinki 2019 - Specification-Driven Development of REST APIs with Al...
APIdays Helsinki 2019 - Specification-Driven Development of REST APIs with Al...APIdays Helsinki 2019 - Specification-Driven Development of REST APIs with Al...
APIdays Helsinki 2019 - Specification-Driven Development of REST APIs with Al...
 
「リモートペアプロでマントルを突き抜けろ!」AWS Cloud9でリモートペアプロ&楽々サーバーレス開発
「リモートペアプロでマントルを突き抜けろ!」AWS Cloud9でリモートペアプロ&楽々サーバーレス開発「リモートペアプロでマントルを突き抜けろ!」AWS Cloud9でリモートペアプロ&楽々サーバーレス開発
「リモートペアプロでマントルを突き抜けろ!」AWS Cloud9でリモートペアプロ&楽々サーバーレス開発
 
Android networking-2
Android networking-2Android networking-2
Android networking-2
 
Plugins unplugged
Plugins unpluggedPlugins unplugged
Plugins unplugged
 
Intro to @viewport & other new Responsive Web Design CSS features
Intro to @viewport & other new Responsive Web Design CSS featuresIntro to @viewport & other new Responsive Web Design CSS features
Intro to @viewport & other new Responsive Web Design CSS features
 
What’s Your Problem?
What’s Your Problem?What’s Your Problem?
What’s Your Problem?
 
E2 appspresso hands on lab
E2 appspresso hands on labE2 appspresso hands on lab
E2 appspresso hands on lab
 
Building Beautiful REST APIs in ASP.NET Core
Building Beautiful REST APIs in ASP.NET CoreBuilding Beautiful REST APIs in ASP.NET Core
Building Beautiful REST APIs in ASP.NET Core
 
Beautiful REST+JSON APIs with Ion
Beautiful REST+JSON APIs with IonBeautiful REST+JSON APIs with Ion
Beautiful REST+JSON APIs with Ion
 
RESTFUL SERVICES MADE EASY: THE EVE REST API FRAMEWORK - Nicola Iarocci - Co...
RESTFUL SERVICES MADE EASY: THE EVE REST API FRAMEWORK -  Nicola Iarocci - Co...RESTFUL SERVICES MADE EASY: THE EVE REST API FRAMEWORK -  Nicola Iarocci - Co...
RESTFUL SERVICES MADE EASY: THE EVE REST API FRAMEWORK - Nicola Iarocci - Co...
 

Viewers also liked

Port Gardner, Everett - March 2014 Newsletter
Port Gardner, Everett - March 2014 NewsletterPort Gardner, Everett - March 2014 Newsletter
Port Gardner, Everett - March 2014 NewsletterTimothy Ellis
 
6traits pp
6traits pp6traits pp
6traits ppbtartufo
 
Port Gardner, Everett - October Newsletter
Port Gardner, Everett - October NewsletterPort Gardner, Everett - October Newsletter
Port Gardner, Everett - October NewsletterTimothy Ellis
 
Port Gardner, Everett - October 2014 Newsletter
Port Gardner, Everett - October 2014 NewsletterPort Gardner, Everett - October 2014 Newsletter
Port Gardner, Everett - October 2014 NewsletterTimothy Ellis
 
Port Gardner, Everett - May 2014 Newsletter
Port Gardner, Everett - May 2014 NewsletterPort Gardner, Everett - May 2014 Newsletter
Port Gardner, Everett - May 2014 NewsletterTimothy Ellis
 
Presentation1
Presentation1Presentation1
Presentation1mcarroll1
 
History of the Internet
History of the InternetHistory of the Internet
History of the InternetBianca_04
 
3 la gramàtica. morf nominal power
3 la gramàtica. morf nominal power3 la gramàtica. morf nominal power
3 la gramàtica. morf nominal powerpilar
 
Marketing Findings & Implications
Marketing Findings & ImplicationsMarketing Findings & Implications
Marketing Findings & ImplicationsKalyna Hanover
 
Thoughts on Paper. Summary of Discussion with Prospect.
Thoughts on Paper. Summary of Discussion with Prospect.Thoughts on Paper. Summary of Discussion with Prospect.
Thoughts on Paper. Summary of Discussion with Prospect.Kalyna Hanover
 
「INFOGRAPHIC」 The Great 21st Century North American War: Unicorns vs Narwhals
「INFOGRAPHIC」 The Great 21st Century North American War: Unicorns vs Narwhals「INFOGRAPHIC」 The Great 21st Century North American War: Unicorns vs Narwhals
「INFOGRAPHIC」 The Great 21st Century North American War: Unicorns vs Narwhalsdomain .ME
 

Viewers also liked (16)

Port Gardner, Everett - March 2014 Newsletter
Port Gardner, Everett - March 2014 NewsletterPort Gardner, Everett - March 2014 Newsletter
Port Gardner, Everett - March 2014 Newsletter
 
6traits pp
6traits pp6traits pp
6traits pp
 
Port Gardner, Everett - October Newsletter
Port Gardner, Everett - October NewsletterPort Gardner, Everett - October Newsletter
Port Gardner, Everett - October Newsletter
 
Port Gardner, Everett - October 2014 Newsletter
Port Gardner, Everett - October 2014 NewsletterPort Gardner, Everett - October 2014 Newsletter
Port Gardner, Everett - October 2014 Newsletter
 
Port Gardner, Everett - May 2014 Newsletter
Port Gardner, Everett - May 2014 NewsletterPort Gardner, Everett - May 2014 Newsletter
Port Gardner, Everett - May 2014 Newsletter
 
Presentation1
Presentation1Presentation1
Presentation1
 
Voic epp
Voic eppVoic epp
Voic epp
 
Internet 2556 แก้ไข
Internet 2556 แก้ไขInternet 2556 แก้ไข
Internet 2556 แก้ไข
 
History of the Internet
History of the InternetHistory of the Internet
History of the Internet
 
Converting in metric
Converting in metricConverting in metric
Converting in metric
 
3 la gramàtica. morf nominal power
3 la gramàtica. morf nominal power3 la gramàtica. morf nominal power
3 la gramàtica. morf nominal power
 
Marketing Findings & Implications
Marketing Findings & ImplicationsMarketing Findings & Implications
Marketing Findings & Implications
 
Thoughts to Consider
Thoughts to ConsiderThoughts to Consider
Thoughts to Consider
 
Marketing Plan Sample
Marketing Plan SampleMarketing Plan Sample
Marketing Plan Sample
 
Thoughts on Paper. Summary of Discussion with Prospect.
Thoughts on Paper. Summary of Discussion with Prospect.Thoughts on Paper. Summary of Discussion with Prospect.
Thoughts on Paper. Summary of Discussion with Prospect.
 
「INFOGRAPHIC」 The Great 21st Century North American War: Unicorns vs Narwhals
「INFOGRAPHIC」 The Great 21st Century North American War: Unicorns vs Narwhals「INFOGRAPHIC」 The Great 21st Century North American War: Unicorns vs Narwhals
「INFOGRAPHIC」 The Great 21st Century North American War: Unicorns vs Narwhals
 

Similar to Ams adapters

Cdm mil-18 - hypermedia ap is for headless platforms and data integration
Cdm mil-18 - hypermedia ap is for headless platforms and data integrationCdm mil-18 - hypermedia ap is for headless platforms and data integration
Cdm mil-18 - hypermedia ap is for headless platforms and data integrationDavid Gómez García
 
Automatic discovery of Web API Specifications: an example-driven approach
Automatic discovery of Web API Specifications: an example-driven approachAutomatic discovery of Web API Specifications: an example-driven approach
Automatic discovery of Web API Specifications: an example-driven approachJordi Cabot
 
Solutions for bi-directional integration between Oracle RDBMS & Apache Kafka
Solutions for bi-directional integration between Oracle RDBMS & Apache KafkaSolutions for bi-directional integration between Oracle RDBMS & Apache Kafka
Solutions for bi-directional integration between Oracle RDBMS & Apache KafkaGuido Schmutz
 
Solutions for bi-directional Integration between Oracle RDMBS & Apache Kafka
Solutions for bi-directional Integration between Oracle RDMBS & Apache KafkaSolutions for bi-directional Integration between Oracle RDMBS & Apache Kafka
Solutions for bi-directional Integration between Oracle RDMBS & Apache KafkaGuido Schmutz
 
Solutions for bi-directional integration between Oracle RDBMS and Apache Kafk...
Solutions for bi-directional integration between Oracle RDBMS and Apache Kafk...Solutions for bi-directional integration between Oracle RDBMS and Apache Kafk...
Solutions for bi-directional integration between Oracle RDBMS and Apache Kafk...confluent
 
SDKs, the good the bad the ugly - Japan
SDKs, the good the bad the ugly - JapanSDKs, the good the bad the ugly - Japan
SDKs, the good the bad the ugly - Japantristansokol
 
Full-Text Search Explained - Philipp Krenn - Codemotion Rome 2017
Full-Text Search Explained - Philipp Krenn - Codemotion Rome 2017Full-Text Search Explained - Philipp Krenn - Codemotion Rome 2017
Full-Text Search Explained - Philipp Krenn - Codemotion Rome 2017Codemotion
 
Designing REST API automation tests in Kotlin
Designing REST API automation tests in KotlinDesigning REST API automation tests in Kotlin
Designing REST API automation tests in KotlinDmitriy Sobko
 
Real-time search in Drupal with Elasticsearch @Moldcamp
Real-time search in Drupal with Elasticsearch @MoldcampReal-time search in Drupal with Elasticsearch @Moldcamp
Real-time search in Drupal with Elasticsearch @MoldcampAlexei Gorobets
 
Getting into ember.js
Getting into ember.jsGetting into ember.js
Getting into ember.jsreybango
 
Building Advanced Serverless Applications
Building Advanced Serverless ApplicationsBuilding Advanced Serverless Applications
Building Advanced Serverless ApplicationsAmazon Web Services
 
Stratalux Cloud Formation and Chef Integration Presentation
Stratalux Cloud Formation and Chef Integration PresentationStratalux Cloud Formation and Chef Integration Presentation
Stratalux Cloud Formation and Chef Integration PresentationJeremy Przygode
 
Use Angular Schematics to Simplify Your Life - Develop Denver 2019
Use Angular Schematics to Simplify Your Life - Develop Denver 2019Use Angular Schematics to Simplify Your Life - Develop Denver 2019
Use Angular Schematics to Simplify Your Life - Develop Denver 2019Matt Raible
 
Document Conversion & Retrieve and Rank 一問一答
Document Conversion & Retrieve and Rank 一問一答Document Conversion & Retrieve and Rank 一問一答
Document Conversion & Retrieve and Rank 一問一答Hisashi Komine
 
Introduction to GraphQL and AWS Appsync on AWS - iOS
Introduction to GraphQL and AWS Appsync on AWS - iOSIntroduction to GraphQL and AWS Appsync on AWS - iOS
Introduction to GraphQL and AWS Appsync on AWS - iOSAmazon Web Services
 
A Gentle Introduction to Angular Schematics - Devoxx Belgium 2019
A Gentle Introduction to Angular Schematics - Devoxx Belgium 2019A Gentle Introduction to Angular Schematics - Devoxx Belgium 2019
A Gentle Introduction to Angular Schematics - Devoxx Belgium 2019Matt Raible
 
Pentesting Modern Web Apps: A Primer
Pentesting Modern Web Apps: A PrimerPentesting Modern Web Apps: A Primer
Pentesting Modern Web Apps: A PrimerBrian Hysell
 

Similar to Ams adapters (20)

Cdm mil-18 - hypermedia ap is for headless platforms and data integration
Cdm mil-18 - hypermedia ap is for headless platforms and data integrationCdm mil-18 - hypermedia ap is for headless platforms and data integration
Cdm mil-18 - hypermedia ap is for headless platforms and data integration
 
Automatic discovery of Web API Specifications: an example-driven approach
Automatic discovery of Web API Specifications: an example-driven approachAutomatic discovery of Web API Specifications: an example-driven approach
Automatic discovery of Web API Specifications: an example-driven approach
 
Solutions for bi-directional integration between Oracle RDBMS & Apache Kafka
Solutions for bi-directional integration between Oracle RDBMS & Apache KafkaSolutions for bi-directional integration between Oracle RDBMS & Apache Kafka
Solutions for bi-directional integration between Oracle RDBMS & Apache Kafka
 
Solutions for bi-directional Integration between Oracle RDMBS & Apache Kafka
Solutions for bi-directional Integration between Oracle RDMBS & Apache KafkaSolutions for bi-directional Integration between Oracle RDMBS & Apache Kafka
Solutions for bi-directional Integration between Oracle RDMBS & Apache Kafka
 
Solutions for bi-directional integration between Oracle RDBMS and Apache Kafk...
Solutions for bi-directional integration between Oracle RDBMS and Apache Kafk...Solutions for bi-directional integration between Oracle RDBMS and Apache Kafk...
Solutions for bi-directional integration between Oracle RDBMS and Apache Kafk...
 
SDKs, the good the bad the ugly - Japan
SDKs, the good the bad the ugly - JapanSDKs, the good the bad the ugly - Japan
SDKs, the good the bad the ugly - Japan
 
Full-Text Search Explained - Philipp Krenn - Codemotion Rome 2017
Full-Text Search Explained - Philipp Krenn - Codemotion Rome 2017Full-Text Search Explained - Philipp Krenn - Codemotion Rome 2017
Full-Text Search Explained - Philipp Krenn - Codemotion Rome 2017
 
Elastic tire demo
Elastic tire demoElastic tire demo
Elastic tire demo
 
Designing REST API automation tests in Kotlin
Designing REST API automation tests in KotlinDesigning REST API automation tests in Kotlin
Designing REST API automation tests in Kotlin
 
Real-time search in Drupal with Elasticsearch @Moldcamp
Real-time search in Drupal with Elasticsearch @MoldcampReal-time search in Drupal with Elasticsearch @Moldcamp
Real-time search in Drupal with Elasticsearch @Moldcamp
 
Getting into ember.js
Getting into ember.jsGetting into ember.js
Getting into ember.js
 
Building Advanced Serverless Applications
Building Advanced Serverless ApplicationsBuilding Advanced Serverless Applications
Building Advanced Serverless Applications
 
Stratalux Cloud Formation and Chef Integration Presentation
Stratalux Cloud Formation and Chef Integration PresentationStratalux Cloud Formation and Chef Integration Presentation
Stratalux Cloud Formation and Chef Integration Presentation
 
Workshop 17: EmberJS parte II
Workshop 17: EmberJS parte IIWorkshop 17: EmberJS parte II
Workshop 17: EmberJS parte II
 
Use Angular Schematics to Simplify Your Life - Develop Denver 2019
Use Angular Schematics to Simplify Your Life - Develop Denver 2019Use Angular Schematics to Simplify Your Life - Develop Denver 2019
Use Angular Schematics to Simplify Your Life - Develop Denver 2019
 
Document Conversion & Retrieve and Rank 一問一答
Document Conversion & Retrieve and Rank 一問一答Document Conversion & Retrieve and Rank 一問一答
Document Conversion & Retrieve and Rank 一問一答
 
Introduction to GraphQL and AWS Appsync on AWS - iOS
Introduction to GraphQL and AWS Appsync on AWS - iOSIntroduction to GraphQL and AWS Appsync on AWS - iOS
Introduction to GraphQL and AWS Appsync on AWS - iOS
 
Introduction to JavaScript Basics.
Introduction to JavaScript Basics.Introduction to JavaScript Basics.
Introduction to JavaScript Basics.
 
A Gentle Introduction to Angular Schematics - Devoxx Belgium 2019
A Gentle Introduction to Angular Schematics - Devoxx Belgium 2019A Gentle Introduction to Angular Schematics - Devoxx Belgium 2019
A Gentle Introduction to Angular Schematics - Devoxx Belgium 2019
 
Pentesting Modern Web Apps: A Primer
Pentesting Modern Web Apps: A PrimerPentesting Modern Web Apps: A Primer
Pentesting Modern Web Apps: A Primer
 

Recently uploaded

"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embeddingZilliz
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfRankYa
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr LapshynFwdays
 
The Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfThe Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfSeasiaInfotech2
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024The Digital Insurer
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 

Recently uploaded (20)

"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embedding
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdf
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
 
The Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfThe Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdf
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 

Ams adapters

  • 1. Why AMS Adapters, in Rails 5, are so important to a wonderful RESTful API
  • 2. { "data": { "type": "Developer", "id": "Tiago Freire", "attributes": { "nickname" : "Kuruma", "background_knowledge": [ "C", "C++", "C#", "Java"], "current_language:": "Ruby", "interest": "Rust" }, "relationships": { "jobs": { "data": { "type": "Software Boutique", "id": "Codeminer42" }, "links": { "related": { "href": "http://www.codeminer42.com" } } }, "consultancy": { "data": { "type": "Host and Cloud services", "id": "Locaweb" }, "links": { "related": { "href": "http://www.locaweb.com.br" } } } } } }
  • 3. { "data": { "type": "Developer", "id": "Bruno Bacarini", "attributes": { "nickname" : "bacarini", "background_knowledge": ["Java"], "current_language:": "Ruby" }, "relationships": { "jobs": [ { "data": { "type": "Host and Cloud services", "id": "Locaweb" }, "links": { "related": { "href": "http://www.locaweb.com.br" } } },{ "data": { "type": "e-recruitment", "id": "VAGAS.com" }, "links": { "related": { "href": "http://www.vagas.com.br" } } }] } } }
  • 4. Developer Experience JSON API Rails 5Rails 5 REST API AMS Hypermedia Adapters Patterns Documentation
  • 9.
  • 10. ProtocolProtocol HTTPHTTP The Hypertext Transfer Protocol (HTTP) is a stateless application-level protocol for distributed, collaborative, hypertext information systems.
  • 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
  • 12. HTTP verbsHTTP verbs [C] POST [R] GET [U] PUT / PATCH [D] DELETE
  • 13. Hypermedia controlHypermedia control Machines can follow links when they understand the data format and relationship types. Roy T. Fielding
  • 14. So, where are the links?
  • 15.
  • 19.
  • 22.
  • 24.
  • 25. rails new appname --apirails new appname --api
  • 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
  • 30.
  • 31.
  • 34. How to use adaptersHow to use adapters (Specially JsonAPI)?(Specially JsonAPI)?
  • 35. #controller/action render json: @posts, adapter: :json_api #OR #config/initializer ActiveModel::Serializer.config.adapter = :json_api
  • 36.
  • 37. Accept: application/vnd.example[.version].param[+json] curl -v -H 'Accept:application/vnd.example.v1+json' localhost:3000 ActiveModel::Serializer::Adapter.register(:json_v1, Json) ActiveModel::Serializer::Adapter.register(:json_v2, JsonApi)
  • 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
  • 39. Creating my ownCreating my own adapteradapter
  • 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
  • 43. #app/serializers class PostSerializer < ActiveModel::Serializer attributes :id, :title has_many :comments has_one :author end
  • 44. "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" } }],
  • 45. class PostsController < ApplicationController def show @post = Post.find params[:id] render json: @post, adapter: :json_api, include: ['comments', 'author'] end end
  • 46. "included": [{ "type": "people", "id": "9", "attributes": { "first-name": "Dan", "last-name": "Gebhardt", "twitter": "dgeb" }, "links": { "self": "http://example.com/people/9" } }, { "type": "comments", "id": "5", "attributes": { "body": "First!" }, "links": { "self": "http://example.com/comments/5" } }],
  • 48. class PostsController < ApplicationController def show @post = Post.find params[:id] render json: @post, adapter: :json_api, include: [author: [:bio]] end end class PostSerializer < ActiveModel::Serializer attributes :id, :name has_many :author end class AuthorSerializer < ActiveModel::Serializer attributes :id, :name has_one :bio end class BioSerializer < ActiveModel::Serializer attributes :id, :title belongs_to :author end
  • 49. "included": [ { "id": "1", "type": "author", "attributes": { "name": "bruno" }, "relationships": { "bio": { "data": [ { "id": "1", "type": "bio" } ] } } }, { "id": "1", "type": "bio", "attributes": { "title": "foobar" } },
  • 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
  • 51.
  • 52.
  • 53. "links": { "self": "http://example.com/posts?page%5Bnumber%5D=3&page%5Bsize%5D=1", "first": "http://example.com/posts?page%5Bnumber%5D=1&page%5Bsize%5D=1", "prev": "http://example.com/posts?page%5Bnumber%5D=2&page%5Bsize%5D=1", "next": "http://example.com/posts?page%5Bnumber%5D=4&page%5Bsize%5D=1", "last": "http://example.com/posts?page%5Bnumber%5D=10&page%5Bsize%5D=1" }
  • 54. class PostsController < ApplicationController def show @post = Post.find params[:id] render json: @post, adapter: :json_api, meta: { "total-pages" => 10 } end end "meta": { "total-pages": 10 }
  • 55. { "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" } }], "included": [{ "type": "people", "id": "9", "attributes": { "first-name": "Dan", "last-name": "Gebhardt", "twitter": "dgeb" }, "links": { "self": "http://example.com/people/9" } }, { "type": "comments", "id": "5", "attributes": { "body": "First!" }, "links": { "self": "http://example.com/comments/5" } }], "links": { "self": "http://example.com/posts?page%5Bnumber%5D=3&page%5Bsize%5D=1", "first": "http://example.com/posts?page%5Bnumber%5D=1&page%5Bsize%5D=1", "prev": "http://example.com/posts?page%5Bnumber%5D=2&page%5Bsize%5D=1", "next": "http://example.com/posts?page%5Bnumber%5D=4&page%5Bsize%5D=1", "last": "http://example.com/posts?page%5Bnumber%5D=10&page%5Bsize%5D=1" }, "meta": { "total-pages": 10 } }
  • 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
  • 60.