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