{ json:api }

A specification for building APIs in JSON

#MDW2018

Speaker

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

Agenda

  • What's web service?
  • Web Services Standards and Protocols
  • RESTful API
  • JSON-API
  • Demo

#MDW2018

what's a web service ?

It's a method of communication between two or more applications for exchanging data over network

Web Service Standards and Protocols

  • XML-RPC
  • SOAP
  • REST

XML-RPC

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

Request

Response

<?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>

SOAP

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

Request

Response

<?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>

Both Are XML-Based!

Favored by Enterprises :)

XML-RPC + SOAP

REST

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

Richardson
Maturity
Model

steps toward the glory of REST

By Martin Fowler

https://martinfowler.com/articles/richardsonMaturityModel.html

The Steps

Level 0

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

Level 0

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>
</openSlotList

Query Hospital to get the open slots

Level 0

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

Level 1

So now rather than making all our requests to a singular service endpoint, we now start talking to individual resources

what's the resource ?

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

Level 1

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

Level 1

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

Level 2

We need to use the HTTP verbs as closely as possible to how they are used in HTTP itself.

what's the HTTP Verb  ?

HTTP defines a set of request verbs to indicate the desired action to be performed for a given resource.

HTTP Verbs (Methods)

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

1

HTTP Verbs (Methods)

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

2

HTTP Verbs (Methods)

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

3

HTTP Verbs (Methods)

Verb Functionality Features
DELETE deletes the specified resource Idempotent

4

Level 2

GET /doctors/mjones/slots?date=20100104&status=open HTTP/1.1
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

Level 2

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

HTTP Status Codes

200

404

409

201

OK

Created

! found

Conflict

https://httpstatuses.com/

401

Unauthorized

422

Unprocessable Entity

500

Internal Server Err

503

Service Unavailabe

HTTP Status Codes

418

Level 3

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

Level 3

GET /doctors/mjones/slots?date=20100104&status=open HTTP/1.1
HTTP/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

REST Vs SOAP

http://geek-and-poke.com

{ json:api }

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

Content negotiation

Accept: application/json; q=0.5, application/xml; q=0.001

JSON API

Accept: application/vnd.api+json

Document Structure

{
  "data": {
    "type": "articles",
    "id": "1",
    "attributes": {
      // ... this article's attributes
    },
    "relationships": {
      // ... this article's relationships
    }
  }
}

Document Structure

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”.

Document Structure

A document MUST contain at least one of the following top-level members:

  • data: the document’s “primary data”
  • errors: an array of error objects
  • meta: a meta object that contains non-standard meta-information.

The members data and errors MUST NOT coexist in the same document

Document Structure

A document MAY contain any of these top-level members:

  • jsonapi: an object describing the server’s implementation
  • links: a links object related to the primary data.
  • included: an array of resource objects that are related to the primary data and/or each other (“included resources”).

Resource Objects

{
  "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" }
    }
  }
}

Resource Objects

Every resource object MUST contain an id member and a type member. The values of the id and type members MUST be strings.

Resource Objects

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 Information

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"
    ]
  }
}

Links

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
    }
  }
}

Fetching Data

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+json

Fetching Relationships

A 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+json

Inclusion of Related Resources

An 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.

Inclusion of Related Resources

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+json

Sparse Fieldsets

GET /articles?include=author&fields[articles]=title,body&fields[people]=name HTTP/1.1
Accept: application/vnd.api+json

A client MAY request that an endpoint return only specific fields in the response on a per-type basis by including a fields[TYPE] parameter.

Sorting

GET /people?sort=age HTTP/1.1
Accept: application/vnd.api+json

An endpoint MAY support requests to sort the primary data with a sort query parameter. The value for sort MUST represent sort fields.

Sorting

GET /articles?sort=-created,title HTTP/1.1
Accept: application/vnd.api+json

The 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.

Pagination

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”).

Creating Resources

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.

Creating Resources

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" }
      }
    }
  }
}

Updating Resources

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"
    }
  }
}

Updating Relationships

PATCH /articles/1/relationships/author HTTP/1.1
Content-Type: application/vnd.api+json
Accept: application/vnd.api+json

{
  "data": { "type": "people", "id": "12" }
}

Deleting Resources

DELETE /photos/1 HTTP/1.1
Accept: application/vnd.api+json

Thank You