A specification for building APIs in JSON
#MDW2018
My Name is Islam Askar
Open Source Department Deputy Head - ITI
Developer, Freelancer, Travel lover, Caffeine addicted and father of two :)
http://islam.askar.site
@islamaskar
Ruby, Rails, JavaScript, ReactJS, NodeJS, PHP, Zend Framework, Perl + LINUX!
TDD, BDD, Applications Architecture, MicroServices, DevOps
/islamaskar
#MDW2018
#MDW2018
It's a method of communication between two or more applications for exchanging data over network
XML-RPC is among the simplest and most foolproof web service approaches that makes it easy for computers to call procedures on other computers.
Remote
Procedure
Call
Created in 1998 by Dave Winer of UserLand Software and Microsoft
<?xml version="1.0"?>
<methodCall>
<methodName>circleArea</methodName>
<params>
<param>
<value><double>2.41</double></value>
</param>
</params>
</methodCall><?xml version="1.0"?>
<methodResponse>
<params>
<param>
<value><double>18.24668429131</double></value>
</param>
</params>
</methodResponse>XML-based messaging protocol for exchanging information among computers. Although SOAP can be delivered via a variety of transport protocols, the initial focus of SOAP is remote procedure calls transported via HTTP
Simple
Object
Access
Protocol
Improvement over XML-RPC and was designed by Dave Winer, Don Box, Bob Atkinson, and Mohsen Al-Ghosein for Microsoft
Since Ver 1.2 it became a W3C recommendation on June 24, 2003
<?xml version = "1.0"?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV = "http://www.w3.org/2001/12/soap-envelope"
SOAP-ENV:encodingStyle = "http://www.w3.org/2001/12/soap-encoding">
<SOAP-ENV:Body xmlns:m = "http://www.xyz.org/quotations">
<m:GetQuotation>
<m:QuotationsName>MiscroSoft</m:QuotationsName>
</m:GetQuotation>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope><?xml version = "1.0"?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV = "http://www.w3.org/2001/12/soap-envelope"
SOAP-ENV:encodingStyle = "http://www.w3.org/2001/12/soap-encoding">
<SOAP-ENV:Body xmlns:m = "http://www.xyz.org/quotation">
<m:GetQuotationResponse>
<m:Quotation>Here is the quotation</m:Quotation>
</m:GetQuotationResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>XML-RPC + SOAP
REST as a concept was introduced by Roy Fielding in his doctoral thesis, named Architectural Styles and the Design of Network-based Software Architectures in 2000
REpresentational
State
Transfer
By Martin Fowler
https://martinfowler.com/articles/richardsonMaturityModel.html
The starting point for the model is using HTTP as a transport system for remote interactions, but without using any of the mechanisms of the web.
Same as XML-RPC and SOAP
POST /appointmentService HTTP/1.1
[various other headers]
<openSlotRequest date = "2010-01-04" doctor = "mjones"/><openSlotList>
<slot start = "1400" end = "1450">
<doctor id = "mjones"/>
</slot>
<slot start = "1600" end = "1650">
<doctor id = "mjones"/>
</slot>
</openSlotListQuery Hospital to get the open slots
POST /appointmentService HTTP/1.1
[various other headers]
<appointmentRequest>
<slot doctor = "mjones" start = "1400" end = "1450"/>
<patient id = "jsmith"/>
</appointmentRequest>HTTP/1.1 200 OK
[various headers]
<appointment>
<slot doctor = "mjones" start = "1400" end = "1450"/>
<patient id = "jsmith"/>
</appointment>Book the free slot
So now rather than making all our requests to a singular service endpoint, we now start talking to individual resources
It's basically "whatever thing is accessed by the URL you supply", resources are just concepts, always represented as noun and every resource can have one or more representation
POST /doctors/mjones HTTP/1.1
[various other headers]
<openSlotRequest date = "2010-01-04"/>HTTP/1.1 200 OK
[various headers]
<openSlotList>
<slot id = "1234" doctor = "mjones" start = "1400" end = "1450"/>
<slot id = "5678" doctor = "mjones" start = "1600" end = "1650"/>
</openSlotList>Query Hospital to get the open slots
POST /slots/1234 HTTP/1.1
[various other headers]
<appointmentRequest>
<patient id = "jsmith"/>
</appointmentRequest>HTTP/1.1 200 OK
[various headers]
<appointment>
<slot id = "1234" doctor = "mjones" start = "1400" end = "1450"/>
<patient id = "jsmith"/>
</appointment>Book the free slot
We need to use the HTTP verbs as closely as possible to how they are used in HTTP itself.
HTTP defines a set of request verbs to indicate the desired action to be performed for a given resource.
| Verb | Functionality | Features |
|---|---|---|
| GET | requests a representation of the specified resource, should only retrieve data | Safe, Idempotent, Cacheable |
| HEAD | asks for a response identical to that of a GET request, but without the response body | Safe, Idempotent, Cacheable |
| Verb | Functionality | Features |
|---|---|---|
| OPTIONS | used to describe the communication options for the target resource | Safe, Idempotent, Cacheable |
| POST | used to submit an entity to the specified resource, often causing a change in state or side effects on the server |
| Verb | Functionality | Features |
|---|---|---|
| PUT | replaces all current representations of the target resource with the request payload | Idempotent |
| PATCH | used to apply partial modifications to a resource | Idempotent |
| Verb | Functionality | Features |
|---|---|---|
| DELETE | deletes the specified resource | Idempotent |
GET /doctors/mjones/slots?date=20100104&status=open HTTP/1.1HTTP/1.1 200 OK
[various headers]
<openSlotList>
<slot id = "1234" doctor = "mjones" start = "1400" end = "1450"/>
<slot id = "5678" doctor = "mjones" start = "1600" end = "1650"/>
</openSlotList>Query Hospital to get the open slots
POST /slots/1234 HTTP/1.1
[various other headers]
<appointmentRequest>
<patient id = "jsmith"/>
</appointmentRequest>HTTP/1.1 201 Created
Location: slots/1234/appointment
[various headers]
<appointment>
<slot id = "1234" doctor = "mjones" start = "1400" end = "1450"/>
<patient id = "jsmith"/>
</appointment>Book the free slot
200
404
409
201
OK
Created
! found
Conflict
https://httpstatuses.com/
401
Unauthorized
422
Unprocessable Entity
500
Internal Server Err
503
Service Unavailabe
418
A resource should provide links, so a client that consumes the resource can navigate through and interact with it without knowing any other endpoint except the entry point
this is referred as HATEOAS
Hypertext As The Engine Of Application State
GET /doctors/mjones/slots?date=20100104&status=open HTTP/1.1HTTP/1.1 200 OK
[various headers]
<openSlotList>
<slot id = "1234" doctor = "mjones" start = "1400" end = "1450">
<link rel = "/linkrels/slot/book"
uri = "/slots/1234"/>
</slot>
<slot id = "5678" doctor = "mjones" start = "1600" end = "1650">
<link rel = "/linkrels/slot/book"
uri = "/slots/5678"/>
</slot>
</openSlotList>Book the free slot
Links
http://geek-and-poke.com
First Draft 05/2013 - V1 05/2015
JSON API is a specification for how a client should request that resources be fetched or modified, and how a server should respond to those requests.
JSON API is designed to minimize both the number of requests and the amount of data transmitted between clients and servers.
is a mechanism embedded into HTTP that allows web services to serve different versions (or formats) of the resource.
This is achieved by the Accept group of HTTP headers
Accept: application/json; q=0.5, application/xml; q=0.001Accept: application/vnd.api+json{
"data": {
"type": "articles",
"id": "1",
"attributes": {
// ... this article's attributes
},
"relationships": {
// ... this article's relationships
}
}
}A JSON object MUST be at the root of every JSON API request and response containing data. This object defines a document’s “top level”.
A document MUST contain at least one of the following top-level members:
The members data and errors MUST NOT coexist in the same document
A document MAY contain any of these top-level members:
{
"type": "articles",
"id": "1",
"attributes": {
"title": "Rails is Omakase"
},
"relationships": {
"author": {
"links": {
"self": "/articles/1/relationships/author",
"related": "/articles/1/author"
},
"data": { "type": "people", "id": "9" }
}
}
}Every resource object MUST contain an id member and a type member. The values of the id and type members MUST be strings.
A resource object’s attributes and its relationships are collectively called its “fields”.
Members of the relationships object (“relationships”) represent references from the resource object in which it’s defined to other resource objects.
Relationships may be to-one or to-many.
meta member can be used to include non-standard meta-information. The value of each meta member MUST be an object (a “meta object”).
{
"meta": {
"copyright": "Copyright 2015 Example Corp.",
"authors": [
"Yehuda Katz",
"Steve Klabnik",
"Dan Gebhardt",
"Tyler Kellen"
]
}
}a links member can be used to represent links. The value of each links member MUST be an object
"links": {
"self": "http://example.com/posts",
"related": {
"href": "http://example.com/articles/1/comments",
"meta": {
"count": 10
}
}
}Data, including resources and relationships, can be fetched by sending a GET request to an endpoint.
GET /articles HTTP/1.1
Accept: application/vnd.api+jsonA server MUST support fetching relationship data for every relationship URL provided as a self link as part of a relationship’s links object.
GET /articles/1/relationships/comments HTTP/1.1
Accept: application/vnd.api+jsonAn endpoint MAY return resources related to the primary data by default.
An endpoint MAY also support an include request parameter to allow the client to customize which related resources should be returned.
If an endpoint does not support the include parameter, it MUST respond with 400 Bad Request to any requests that include it.
GET /articles/1?include=comments,author HTTP/1.1
Accept: application/vnd.api+json
---
GET /articles/1?include=comments.author HTTP/1.1
Accept: application/vnd.api+jsonGET /articles?include=author&fields[articles]=title,body&fields[people]=name HTTP/1.1
Accept: application/vnd.api+jsonA client MAY request that an endpoint return only specific fields in the response on a per-type basis by including a fields[TYPE] parameter.
GET /people?sort=age HTTP/1.1
Accept: application/vnd.api+jsonAn endpoint MAY support requests to sort the primary data with a sort query parameter. The value for sort MUST represent sort fields.
GET /articles?sort=-created,title HTTP/1.1
Accept: application/vnd.api+jsonThe sort order for each sort field MUST be ascending unless it is prefixed with a minus (U+002D HYPHEN-MINUS, “-“), in which case it MUST be descending.
A server MAY choose to limit the number of resources returned in a response to a subset (“page”) of the whole set available.
A server MAY provide links to traverse a paginated data set (“pagination links”).
A resource can be created by sending a POST request to a URL that represents a collection of resources. The request MUST include a single resource object as primary data. The resource object MUST contain at least a type member.
POST /photos HTTP/1.1
Content-Type: application/vnd.api+json
Accept: application/vnd.api+json
{
"data": {
"type": "photos",
"attributes": {
"title": "Ember Hamster",
"src": "http://example.com/images/productivity.png"
},
"relationships": {
"photographer": {
"data": { "type": "people", "id": "9" }
}
}
}
}PATCH /articles/1 HTTP/1.1
Content-Type: application/vnd.api+json
Accept: application/vnd.api+json
{
"data": {
"type": "articles",
"id": "1",
"attributes": {
"title": "To TDD or Not"
}
}
}
PATCH /articles/1/relationships/author HTTP/1.1
Content-Type: application/vnd.api+json
Accept: application/vnd.api+json
{
"data": { "type": "people", "id": "12" }
}DELETE /photos/1 HTTP/1.1
Accept: application/vnd.api+json