with Zac Delventhal

Building RESTful APIs

Building RESTful APIs

ish

with Zac Delventhal

Who am I?

  • CS Major for about a year
  • Switched to more in demand field: Acting
  • Joined HRR11
  • HiR with Fulcrum

Today:

  • Senior Software Engineer at Bitwise IO
  • Work on blockchain proof-of-concepts for Intel
  • Use JavaScript, ClojureScript, Python, Node, React

What is a RESTish API?

  • Designed for a client/server relationship
  • Stateless
  • Endpoints describe resources to be interacted with
https://api.github.com/users/delventhalz/repos
  • Resources are manipulated through representations of that resources
POST /users/delventhalz/repos

{
  "name": "hello-world",
  "description": "This is my first repository",
  "homepage": "https://github.com",
  "private": false,
  "has_issues": true,
  "has_wiki": true,
  "has_downloads": true
}

HTTP Verbs

  • Safe - will not modify anything
x++

x = 4
console.log(x)
  • Idempotent - can be called repeatedly with no additional effect

GET

(safe, idempotent, cacheable)

Retrieves a specified resource or group of resources

GET /users

[
  {
    "login": "mojombo",
    "id": 1,
    ...
  },
  {
    "login": "defunkt",
    "id": 2,
    ...
  },
  ...
]
GET /users/delventhalz

{
  "login": "delventhalz",
  "id": 8889580,
  ...
}

POST

Adds a new document to the specified resource

POST /users/delventhalz/repos

{
  "name": "Hello-World",
  "description": "This is your first repository",
  "homepage": "https://github.com",
  "private": false,
  "has_issues": true,
  "has_wiki": true,
  "has_downloads": true
}

PUT

(idempotent)

Replaces a resource with a modified version

PUT /repos/delventhalz/hello-world

{
  "name": "hello-world",
  "description": "This is an updated description",
  "homepage": "https://github.com",
  "private": false,
  "has_issues": true,
  "has_wiki": true,
  "has_downloads": true
}

PATCH

Modify a resource with a partial representation

PATCH /repos/delventhalz/hello-world

{
  "description": "I just can't decide"
}

DELETE

(idempotent)

Removes a resource

DELETE /repos/delventhalz/hello-world
var express = require('express');
var apiRouter = require('./api_router');

var app = express();
app.use('/api' apiRouter);
app.listen(3000);
var express = require('express');
var userHandler = require('./users');
var repoHander = require('./repos');

var apiRouter = express.Router();

apiRouter.get('/users/:username', function(req, res) {
  res.send( userHandler.fetch(req.params.username) );
});

apiRouter.route('/repos/:username/:repo')

  .put(function(req, res) {
    res.send(repoHandler.update(
      req.params.username,
      req.params.repo,
      req.body
    ));
  })

  .delete(function(req, res) {
    res.send(repoHandler.remove(
      req.params.username,
      req.params.repo
    ));
  });

module.exports = apiRouter;

HTTP Verbs

  • GET - (safe, idempotent, cacheable) Requests a specified resource or group of resources
  • POST - Adds a new entity to the specified resource
  • PUT - (idempotent) Replaces a resource with a full representation of the modified version
  • PATCH - Modifies a resource with a partial representation
  • DELETE - (idempotent) Removes a resource

* POST, PUT, and PATCH should always return a full representation of the new resource

/designing/urls

GET /users/:username/repos

thing

identifier

sub-thing

  • URL segments are nouns
  • Categories should be plural
  • URLs should identify a tangible resource
  • Spend time considering what your users will need
GET /user/repos
POST /user/repos
  • Identifying information isn't always explicit
  • Different verbs can use the same endpoint
GET /users/:username/starred
POST /account/update_profile_image
  • Aliases for some common behavior are useful
  • WARNING aliases will anger the Roy Fielding!
https://api.github.com/...
https://www.github.com/api/
  • Make sure you don't conflict with your static pages

?query=strings

.../repos?sort=created,updated&direction=ascending

key

value

more queries

  • Useful way to add controls and specifications to requests
  • Typically used with GETs

comma separated

  • limit
  • offset
  • sort
  • fields
  • omit
  • embed
  • any property name (i.e. status=open)

Common Parameters

Odds and Ends

Version your APIs

  • Using the URL is common:
  • Using HTTP headers is more "correct"
/api/v3/users/delventhalz

Errors

  • 4XX - the clients fault (i.e. 404)
  • 5XX - the server's fault

HATEOAS

  • Hypertext As The Engine Of Application State
  • A web page is this
  • An API is not

Resources

Building RESTish APIs

By delventhalz

Building RESTish APIs

  • 593