No REST for the wicked

Howtos, Tricks and Tips to build REST Servers

Gavin Mogan

Code Monkey @ Sauce Labs

Whats going on?

  • Demonstration
  • How HTTP Works (basics)
  • Examples
  • "Best" Practices

Live Demo time

I need a volunteer

How does it work?

HTTP is made up of headers and bodies. Both on the request and the response side of things.

 

GET /index.html HTTP/1.1
Host: www.example.com
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-CA,en;q=0.8
Cache-Control: max-age=0
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36
HTTP/1.1 200 OK
Date: Mon, 23 May 2005 22:38:34 GMT
Content-Type: text/html; charset=UTF-8
Content-Encoding: UTF-8
Content-Length: 138
Last-Modified: Wed, 08 Jan 2003 23:11:55 GMT
Server: Apache/1.3.3.7 (Unix) (Red-Hat/Linux)
ETag: "3f80f-1b6-3e1cb03b"
Accept-Ranges: bytes
Connection: close

<html><head><title>An Example Page</title></head>
<body>Hello World, this is a very simple HTML document.</body></html>

Request

Response

Lets see if the demo gods like us

GET

  • Getting Data
  • Should not change state
  • Should be repeatable

Ex: Image

POST

  • Sending Data
  • Modifies state
  • No guarantees if sending again will do the same thing

Ex:  Login Form

Types of HTTP Requests (1.0 - Simplified)

HEAD

  • Just returns header, no body
  • Not really going to cover

HTTP/1.1 Added More

  • OPTIONS
  • PUT
  • DELETE
  • TRACE
  • CONNECT

PUT

  • Idempotent
  • "Save"
  • "Store at this location"

DELETE

  • Idempotent
  • Delete this item if exists

Okay, how do I do it?

Bare Bones

  • Sinatra (ruby)
  • Flask (python)
  • Express/Connect (node)
  • PHP

Frameworks

  • Rails (ruby)
  • Django (python)
  • Express + Sequalize (node)
  • Kohana (php)
  • Sympony (php)

Sinatra (ruby)

Flask (python)

require 'sinatra'

get '/hi' do
  "Hello World!"
end
from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello World!"

if __name__ == "__main__":
    app.run()
var express = require('express');
var app = express();

app.get('/', function (req, res) {
  res.send('Hello World!');
});

app.listen(3000, function () {
  console.log('Example app listening on port 3000!');
});

Express (node)

<?php echo "Hello World";

PHP

Bare Bones

Rails (ruby)

$ rails new blog
# it does some stuff
$ cd blog
$ ls
app  bin  config  config.ru  db  Gemfile  Gemfile.lock  lib  log  public  Rakefile  README.rdoc  test  tmp  vendor
$ bin/rails generate controller Welcome index
      create  app/controllers/welcome_controller.rb
       route  get "welcome/index"
      invoke  erb
      create    app/views/welcome
      create    app/views/welcome/index.html.erb
      invoke  test_unit
      create    test/controllers/welcome_controller_test.rb
      invoke  helper
      create    app/helpers/welcome_helper.rb
      invoke    test_unit
      create      test/helpers/welcome_helper_test.rb
      invoke  assets
      invoke    coffee
      create      app/assets/javascripts/welcome.js.coffee
      invoke    scss
      create      app/assets/stylesheets/welcome.css.scss
$ rails server
=> Booting WEBrick
=> Rails 4.0.4 application starting in development on http://0.0.0.0:3000
=> Run `rails server -h` for more startup options
=> Ctrl-C to shutdown server
[2016-07-18 22:06:05] INFO  WEBrick 1.3.1
[2016-07-18 22:06:05] INFO  ruby 2.0.0 (2014-11-13) [x86_64-linux]

Gives you everything

"Best" Practices

URL Schemas

  • GET /resource - should return all
  • GET /resource/id - should return one

 

  • POST /resource - should add one

 

  • PUT/POST /resource/id - should update/store one

 

  • DELETE /resource/id - should delete one

Response Code

  • 200 - All good
  • 201 - Created Successfully
  • 301 - Always look here instead
  • 302 - Look here instead
  • 401 - Security pls. Who are you?
  • 402 - Not allowed
  • 404 - Not found
  • 418 - I'm a little tea pot
  • 500 - PANIC ERROR HAS HAPPENED

JSON vs XML vs YAML

Tooling

Browser Tools

Documentation

  • Github self documents all their urls
    • See https://api.github.com/repos/appium/appium
  • Swagger, Blueprint, Probably more
  • Lots of companies roll their own.
  • Documentation is hard
  • Provide Examples
    • Snippets
    • Downloadable examples

Thanks

Gavin Mogan

Made with Slides.com