Как спроектировать rest api


Приветствую друзья! В этой статье будет краткий мануал по проектированию интерфейса rest api, рассмотрим частые ошибки и используемые стандарты.

Поехали!


Версия api

Чтобы в дальнейшем не было проблем с поддержкой, рекомендуется разделять api по версиям. Сделать это можно добавив название мажорной версии в url

/api/v1/users/1

/api/v2/users/1

...

Лучше использовать версионирование api, чем не использовать

Правила именования роутов


Не используем слэш в конце url

Ко многим разделам вашего api могут идти дополнительные атрибуты, и не всегда интуитивно понятно что их можно добавить если на конце стоит закрывающий слэш

/api/v1/posts
/api/v1/posts/ // не верно

/api/v1/posts/categories
/api/v1/posts/categories/ // не верно

/api/v1/posts?offset=12
/api/v1/posts/?offset=12 // не верно

Именование во множественном числе

Старайтесь всегда называть разделы api во множественном числе, так как существуют слова употребляемые только во множественном числе (glasses, money, clothes), и чтобы в дальнейшем не было путаницы, лучше давать имена в одном стиле

/api/v1/posts
/api/v1/post // не верно

/api/v1/post/categories // не верно
/api/v1/posts/category // не верно
/api/v1/posts/categories

Выборка по id

Чтобы получить например, данные заказа, в api должно быть достаточно передать его id

/api/orders/(( id ))

/api/orders/1

Логическая цепочка

Для того чтобы api было интуитивно понятным, необходимо соблюдать логическую цепочку наименования разделов. К примеру нам нужно получить категории поста, логично сделать так 'Все посты -> конкретный пост -> категории'

/api/v1/posts/1/categories

/api/v1/categories/1 // не верно
/api/v1/categories?post=1 // не верно

Параметры запросов

Как правило параметры задаются в формате get в конце url. К примеру нам нужно получить только пять записей

/api/v1/posts?limit=5

/api/v1/posts/limit/5 // не верно

CRUD - create read update delete

С построением get(получить) запросов мы разобрались, теперь возмемся за создание, изменение, удаление данных. Здесь одним url не обойтись, нам нужны типы запросов POST, PUT, DELETE


Создание - post

Создание записей как правило производится POST запросом на необходимый раздел api, никаких /create/ /build/ /add/ в роуте прописывать не нужно, здесь идет фильтрация типа запроса

К примеру чтобы создать пост, нам нужно отправить POST запрос на подобный url

/api/v1/posts

/api/v1/posts/create // не верно

Чтение - GET

Стандартный get запрос на получение данных


Изменение - PUT

Как и в случае с созданием, url нам править не нужно, нужно только отфильтровать запрос по типу. Для изменения данных используется тип запроса PUT. Вот пример url для изменения поста запросом PUT

/api/v1/posts/1

Удаление - DELETE

Аналогично предыдущим, удаление производится только изменением типа запроса на DELETE

Все действия производятся только с помощью изменения запроса. Никогда не используйте глаголы в url

Ответ сервера

Сервер всегда должен возвращать http коды, вот стандартный список ответов сервера которые обязательно нужно реализовать

  • 200: Done, it was okay. // Обычно GET возвращает этот код.
  • 201: “Done, and created.” // Обычно POST возвращает этот код.
  • 204: “Done, and no body.” // Обычно DELETE возвращает этот код.
  • 400: “Client sent me junk, and I’m not going to mess with it.”
  • 401: “Unauthorized, the client should authenticate first.”
  • 403: “Not allowed. You can’t have it because you logged in but don’t have permission to this thing or to delete this thing.”
  • 404: “Can’t find it.”
  • 410: “Marked as deleted.”
  • 451: “The government made me not show it.”



Пример хорошего api блога

+--------+----------------------------------------+------------------------------------------------------+
|        | POST                                   | login                                                |
|        | POST                                   | logout                                               |
|        | POST                                   | password-recovery                                    |
|        |                                        |                                                      |
|        | GET                                    | posts?offset={n}&limit={n}                           |
|        | POST                                   | posts                                                |
|        | PUT                                    | posts                                                |
|        | DELETE                                 | posts                                                |
|        | GET                                    | posts/{n}/                                           |
|        | GET                                    | posts/{n}/categories                                 |
|        |                                        |                                                      |
|        | GET                                    | categories?offset={n}&limit={n}                      |
|        | POST                                   | categories                                           |
|        | PUT                                    | categories                                           |
|        | DELETE                                 | categories                                           |
+--------+----------------------------------------+------------------------------------------------------+