REST

Лекция 17

REST

  • representational state transfer (en)
  • передача состояния представления (ru)
  • архитектура для построения веб-приложений
  • Рой Филдинг, диссертация, 2000
  • использует семантику запросов-ответов
  • позволяет достичь производительности, надежности, масштабируемости
  • RESTful-системы

REST - Основы

  • клиент-серверная архитектура
  • отсутствие состояния
  • кэширование
  • унифицированный интерфейс
  • слои сервисов
  • доставка кода (необязательно)
  • идентификация ресурсов через URL
  • запрос самоописывает себя
  • изменение состояния через запросы

REST - Сильные стороны

  • производительность (кэширование)
  • надёжность (отсутствие состояния)
  • масштабируемость (отсутствие состояния, простота и предсказуемость интерфеса, лёгкое изменение)

REST - Методы

  • GET - чтение ресурса или коллекции
  • PUT - обновление существующего ресурса или коллекции
  • DELETE - удаление существующего ресурса
  • POST - создание ресурса + все остальные действия

REST - Именование

  • идентификаторы вместо query
  • +: /users/12345
  • -: /api?type=user&id=23
  • -: /users?id=23

REST - Именование

  • используйте иерархию
  • GET /users/12345/comments
  • но не стоит делать слишком большую вложенность
  • 2-3 оптимально

REST - Именование

  • используйте существительные
  • избегайте глаголов
  • +: POST /users
  • -: POST /users/update

REST - Именование

  • используйте множественное число для консистентности
  • +: GET /customers/33245/orders/8769
  • -: GET /customer/33245/order/8769

REST - Именование

  • используйте kebab-case
  • +: GET /customers/33245/delivery-addresses
  • -: GET /customers/33245/deliveryAddresses

REST - Именование

  • не указывайте тип коллекции
  • +: GET /customers
  • -: GET /customer-list

REST - Статус

  • используйте HTTP статусы для ответа
  • 200, 201, 204, 400, 401, 403, 404, 405, 409, 500

REST - Форматы

  • рекомендуется поддерживать json и xml

REST - Версионирование

  • версия API как часть URL
  • версия API - целое число
  • GET /api/v1/users

REST - Версионирование

  • или версионирование схем данных
  • http://api.schemas.wrml.org/soccer/Player
  • http://api.schemas.wrml.org/soccer/Player-2

REST - Ответ


// +
"tags": [
  {"id": "125", "name": "Environment"},
  {"id": "834", "name": "Water Quality"}
]
    

// -
"tags": [
  {"125": "Environment"},
  {"834": "Water Quality"}
]
    

REST - Пагинация

  • limit по-умолчанию
  • информация о пагинации включена в ответ
  • GET /api/v1/users?limit=25&offset=50

{
    "metadata": {
      "count": 308,
      "offset": 50,
      "limit": 25
    },
    "users": [ ... ]
}
    

REST - Сортировка, фильтрация


GET /users?sort=last_name|first_name|-hire_date
GET /users?filter=name::todd|city::denver
    

REST - Ошибки


{
  "message": "The Error",
  "code": "server-error",
  "status": 500,

  // optional
  "developerMessage": "Hi developer!",
  "moreInfo": "http://example.com/server-error"
}
    

REST - Заголовки

  • Content-Type, Accept
  • Cache-Control, Expires, ETag для GET
  • Location для POST
  • If-Unmodified-Since для PUT

REST - HATEOAS


// Hypertext As The Engine Of Application State
// GET /api/v1/
{
  "links": {
    "users": "/api/v1/users"
    "posts": "/api/v1/posts/"
  }
}
    

REST - HATEOAS


// Hypertext As The Engine Of Application State
// GET /api/v1/posts
{
  "links": {
    "post": "/api/v1/posts/:id"
  }
}
    

REST - HATEOAS


// Hypertext As The Engine Of Application State
// GET /api/v1/posts/42
{
  "links": {
    "comments": "/api/v1/posts/42/comments"
  }
}
    

REST - Примеры

REST - Примеры

  • /api/sessions - GET, POST, DELETE
  • /api/users/{login}/password - PUT
  • /api/users/{login}/tokens - DELETE
  • /api/alerts/{id}/activation - GET/POST
  • /api/alerts/{id}/cancellation - GET/POST

REST - Примеры

  • GET /media/{media-id}
  • GET /media/search?lat=48.858844&lng=2.294351
  • GET /media/{media-id}/likes
  • POST /media/{media-id}/likes
  • DELETE /media/{media-id}/likes

REST + Express


// controllers/base.js
...
this.routes = {
  '/': [
    { method: 'get', cb: readAll },
    { method: 'post', cb: create }
  ],
  '/:id': [
    { method: 'get', cb: read },
    { method: 'put', cb: update },
    { method: 'delete', cb: del }
  ]
};
...
    

REST + Express


// controllers/base.js
...
function update(req, res) {
  req.body.id = req.params.id;
  ...
}
...
    

REST - Литература

  • RESTful Service Best Practices / Todd Fredrich
  • REST API Design Rulebook / Mark Masse