REST API:er best practices

Webb helt enkelt #6, 2014-01-30

Webb helt enkelt #7, 2014-04-10

Rickard Andersson

Montania System AB

Webbutveckling, Drift, IT-säkerhet, Linux

PHP, JS, CSS/SCSS.

Symfony, Ember JS

Lite bakgrund

Vårt use case: SPA

ember-data. Active Model Serializer

https://github.com/rails-api/active_model_serializers

HTTP

GET / HTTP/1.1
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8,sv;q=0.6
Connection:keep-alive
Host:www.montania.se
HTTP/1.1 200 OK
Connection:Keep-Alive
Content-Encoding:gzip
Content-Type:text/html; charset=UTF-8
Date:Mon, 20 Jan 2014 19:57:09 GMT
Keep-Alive:timeout=5, max=100
Server:Apache/2.2.24 (Unix) mod_fastcgi/2.4.2 mod_ssl/2.2.24 OpenSSL/0.9.8y

<!doctype html>

REST basics

Använd HTTP till fullo

Resurs URL
Action HTTP Metod
Resultat HTTP status
Filter Query parameter
Format Accept header (alt. filtyp)
Version URL (alt. media type)

Resurser

(URL)
Alla användare /api/users
Enskild användare /api/users/1
Relationer /api/users/1/comments
Relationer /api/comments?ids=1,2,3

Actions

(HTTP metoder)
GET /api/users Hämtar alla användare
GET /api/users/1 Hämtar användare med ID 1
POST /api/users Skapa ny användare
PUT /api/users/1 Uppdatera användare 1
DELETE /api/users/1 Radera användare 1
PUT /api/users Ersätt alla användare
DELETE /api/users Radera alla användare
POST /api/users/1 Delvis uppdatering av användare 1
PATCH /api/users/1 Delvis uppdatering av användare 1

GET /api/users/1?_method=delete

Resultat

(HTTP statuskoder)
GET 200, 404
POST 201, 400, 422
PUT 200, 400, 422, 409
DELETE 204

POST/PUT returnerar Location header

Filter

(Query parameter)

/api/users?name=john

/api/users?offset=100&limit=100

Format

(accept header)
Accept: application/json,text/plain
Content-Type: application/json

Format

(egen mime type)
Accept: application/vnd.user+json
Content-Type: application/vnd.user+json

Format

(filtyp)
GET /api/users.json
Content-Type: application/json

Version

URL /v1/users
Media type application/vnd.user-v1+json

JSON Format

{
    "user": {
        "id":1,
        "username":"rickard",
        "name":"Rickard Andersson",
        "cell":"073-5083445",
        "email":"rickard@montania.se",
        "locked":false,
        "loginCount":15,
        "roles":[1],
        "recipients":[],
        "created":"2014-01-23T14:13:12+0100",
        "updated":"2014-01-23T14:14:25+0100"
    }
}

JSON Format

{
    "user": {
        "id":1,
        "username":"rickard",
        "name":"Rickard Andersson",
        "cell":"073-5083445",
        "email":"rickard@montania.se",
        "locked":false,
        "loginCount":15,
        "roles":[1],
        "recipients":[],
        "created":"2014-01-23T14:13:12+0100",
        "updated":"2014-01-23T14:14:25+0100"
    },
    "roles": [
        {
            "id": 1,
            "created": "2014-01-23T14:13:12+0100",
            "name": "Administratör",
            "role": "ROLE_ADMIN"
        }
    ]
}

JSON API

(ID style)
{
    "posts": [{
        "id": "1",
        "title": "Rails is Omakase",
        "links": {
            "author": "9",
            "comments": [ "5", "12", "17", "20" ]
        }
    }]
}
http://jsonapi.org/

JSON API

(URL style)
{
    "posts": [{
        "id": "1",
        "title": "Rails is Omakase",
        "links": {
            "author": "http://example.com/people/9",
            "comments": "http://example.com/comments/5,12,17,20"
        }
    }]
}
http://jsonapi.org/

Felhantering

HTTP statuskoder

  • 400 Bad Request
  • 401 Unauthorized
  • 403 Forbidden
  • 404 Not Found
  • 405 Method Not Allowed
  • 409 Conflict
  • 422 Unprocessable Entity

Felhantering

Status + meddelande

{
    "status": 409,
    "message": "Conflict"
}

Felhantering

Valideringsfel

{
    "status": 422,
    "message": "Unprocessable Entity",
    "errors": {
        "username": [
            "Detta fält får inte vara tomt"
        ],
        "email": [
            "Detta fält får inte vara tomt"
        ]
    }
}

HATEOAS

Hypermedia as the Engine of Application State

Tips och tricks

  1. Postman
  2. SPDY
  3. Optimera
  4. Var pragmatisk
  5. RPC går oftast att översätta
  6. API fältnamn != DB fältnamn
  7. Komprimering av ids (undvik 414)
  8. JMS Serializer
  9. FOS REST Bundle
  10. Symfony Validator

@rickard2

https://about.me/rickard2
www.montania.se