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
No REST for the wicked: Howtos, Tricks and Tips to build REST Servers (August 2016)
By Gavin Mogan
No REST for the wicked: Howtos, Tricks and Tips to build REST Servers (August 2016)
REST presentation for Code Coffee Vancouver (http://www.meetup.com/Code-Coffee-Vancouver/events/232571483/). Goal was to make building rest services as simple as they are not scary.
- 2,848