Web development & API design

 

06: RESTful design

Today

  • REST levels
     
  • A1 HTTP demo
     
  • (We'll do GraphQL later, I promise)

Assignment 1

  • Feedback ASAP
     
  • Next assignment next week

Hunter, K. (2017) Irresistible APIs, p. 69, Manning

The URL

The Richardson maturity model

Level 1:

Resources

const countries = [
 { name: 'Norway', capital: 'Oslo' },
 { name: 'Denmark', capital: 'Copenhagen' },
];

// read a resource with HTTP GET
app.get('/countries', (req, res) => {
 res.send(counties);
});

// read a specific country
app.get('/countries/:name', (req, res) => {
 const name = req.params.name;
 return res.send(countries.find(
  c => c.name === name
 ));
});

// delete a country
app.get('/countries/:name/delete', (req, res) => {
 const name = req.params.name;
 const index = countries.findIndex(
  c => c.name === name
 );

 // remove the country
 countries.splice(index, 1);
 
 res.send(countries);
});

Level 2:

verbs

const countries = [
 { name: 'Norway', capital: 'Oslo' },
 { name: 'Denmark', capital: 'Copenhagen' },
];

// read a resource with HTTP GET
app.get('/countries', (req, res) => {
 res.send(counties);
});

// read a specific country
app.get('/countries/:name', (req, res) => {
 const name = req.params.name;
 return res.send(countries.find(
  c => c.name === name
 ));
});

// delete a country
app.delete('/countries/:name', (req, res) => {
 const name = req.params.name;
 const index = countries.findIndex(
  c => c.name === name
 );

 // remove the country
 countries.splice(index, 1);
 
 res.send(countries);
});
// old:
app.get('/countries/:name/delete', (req, res) => {

HTTP supports verbs

Hunter, K. (2017) Irresistible APIs, p. 73, Manning

Verbs + URL

  • GET (no payload)
    • /cars
    • /cars/:identifier
       
  • POST /cars
    • { "color": "red", "licence": "AB7839" }
       
  • DELETE: /cars/:identifier
    • No payload
       
  • PUT: /cars/:identifier
    • { "color": "green" }

Title Text

Hunter, K. (2017) Irresistible APIs, p. 69, Manning

Title Text

Hunter, K. (2017) Irresistible APIs, p. 8, Manning

Error handling

  • 500 + "Something went wrong!"
     
  • 200 + "Something went wrong!"?
     
  • 4xx/5xx + { "message": "X went wrong, try Y" }?

WCGW?

  • 1. The network is reliable
     
  • 2. Latency is zero
     
  • 3. Bandwidth is infinite
     
  • 7. Transport cost is zero

https://en.wikipedia.org/wiki/Fallacies_of_distributed_computing

Graceful fallbacks

  • Timeouts for all external calls
     
  • Sane fallbacks (or return a 500 error)
     
  • Circuit breaking
    • Back off if something fails

https://en.wikipedia.org/wiki/Fallacies_of_distributed_computing

https://www.npmjs.com/package/brakes

The Richardson maturity model

Level 3: Hypermedia

I am getting frustrated by the number of people calling any HTTP-based interface a REST API. Today’s example is the SocialSite REST API. That is RPC. It screams RPC. There is so much coupling on display that it should be given an X rating. – Roy Fielding

Hypertext does not need to be HTML on a browser. Machines can follow links when they understand the data format and relationship types. — Roy Fielding (in a comment)

Level 3 requirements

  • A REST API should be entered with no prior knowledge beyond the initial URI (bookmark) and set of standardized media types that are appropriate for the intended audience (i.e., expected to be understood by any client that might use the API).
     
  • A REST API must not define fixed resource names or hierarchies (an obvious coupling of client and server).
     
  • A REST API should spend almost all of its descriptive effort in defining the media type(s) used for representing resources and driving application state, or in defining extended relation names and/or hypertext-enabled mark-up for existing standard media types.

LEvel 3: HATEOAS

Hypermedia As The Engine Of Application State

class Customer {
  constructor(name) {
    this.name = name;
  }
}

// JSON representation
{ 
  "name" : "Alice"
}

// HATEOAS JSON representation
{
  "name": "Alice",
  "links": [ {
    "rel": "self",
    "href": "http://localhost:8080/customer/1"
  } ]
}
  • rel means relationship. For example, an order might have a "rel":"customer" relationship, linking the order to its customer.
     
  • href is a complete URL that uniquely defines the resource.
{
  "content": [ {
    "price": 499.00,
    "description": "Apple tablet device",
    "name": "iPad",
    "links": [ {
      "rel": "self",
      "href": "http://localhost:8080/product/1"
    } ],
    "attributes": {
      "connector": "socket"
    }
  }, {
    "price": 49.00,
    "description": "Dock for iPhone/iPad",
    "name": "Dock",
    "links": [ {
      "rel": "self",
      "href": "http://localhost:8080/product/3"
    } ],
    "attributes": {
      "connector": "plug"
    }
  } ],
  "links": [ {
    "rel": "product.search",
    "href": "http://localhost:8080/product/search"
  } ]
}   

More sophisticated

Level 3 with Node

http 2

http://www.slideshare.net/SimoneBordet/http2-and-java-current-status

A1 HTTP demo

Made with Slides.com