-
Notifications
You must be signed in to change notification settings - Fork 0
Home
Этот документ есть основным соглашение REST-api в компании onCreate
Оглавление
- Основные положения
- Формирование URL
- HTTP глаголы
- Экшены(action) по умолчанию
- Формат общения
- Пагинация
- Фильтры поиска и сортировка
- Система Аутентификации
- Локализация
- Ошибки валидации
- Любое api всегда имеет версию. Версия задается префиксом
//v*/
в начале url. Примерhttps://api.infitting.com/v1/...
- Любое API должно использовать протокол https
- Во всех примерах, а так же в документации к запросам префикс версии не указывается.
- Любое API должно быть задокументировано. Для документации предпочтительно использовать Postman
- Все запросы должны содержать проверки безопасности. К примеру пользователь может редактировать только СВОИ статьи, удалить только СВОИ статьи, а смотреть может ВСЕ статьи.
- Сервер не использует сесии и не хранит никаких временных данных о сеансе. Все необходимое для выполнения запроса клиент должен указать в запросе.
В примере используется сущности:
- Пользователь(user)
- Статья(article) которая принадлежит пользователю
- Комментарий(comment) который принадлежит статье
- url для корневой сущности (например "пользователь")
/users/<id:\d[\d,]*>
- url для вложенной(1-й уровень) сущности(например "статья")
/users/<user_id:\d[\d,]*>/articles/<id:\d[\d,]*>
. Важные моменты:- у пользователя
id
переименован вuser_id
- у последней сущности первичный ключ всегда должен быть назван
id
- у пользователя
- url для дальнейших вложенностей(2-й и глубже) может иметь сформирован двумя способами
/users/<user_id:\d[\d,]*>/articles/<article_id:\d[\d,]*>/comments/<id:\d[\d,]*>
-
/articles/<article_id:\d[\d,]*>/comments/<id:\d[\d,]*>
(предпочтительно) В этом случае первая вложенность опускается, и ссылка становится короче.
- Если в url больше одного первичных ключей, и последний на 100% точно идентифицирует сущность сам по себе, то все предыдущие можно передавать как 0. (сущностей с pk==0 не у нас не бывает). Пример:
PUT /users/2/articles/13
иPUT /users/0/articles/13
должны всегда работать одинаково, при условии что в сущности "статья" id на 100% идентифицирует сущность. - Если сущность состоит из нескольких слов, слова записываются через тире. Пример
super-user
. Без верблюжьей нотации и без подчеркиваний_
. -
Все сущности должны быть названы во множественном числе. Примеры:
users
,articles
,comments
- Если часть url обозначает действие, а не название сущности, нужно писать в единственном числи. Пример
POST /articles/0/comments/1/like
,POST /articles/0/comments/1/spam
. Гдеlike
иspam
обозначает 'поставить метку' лайк и спам соответственно.
Правило одно: можно использовать любые глаголы стандарта http 1.1, и нельзя придумывать свои.
Некоторые HTTP-методы (например: HEAD, GET, OPTIONS и TRACE) определены как безопасные, это означает, что они предназначены только для получения информации и не должны изменять состояние сервера. Другими словами, они не должны иметь побочных эффектов, за исключением безобидных эффектов, таких как: логирование, кеширование, показ баннерной рекламы или увеличение веб-счетчика.
Рекомендуемые глаголы:
- GET - Получить данные | безопасный | Тело: Запрос не имеет. Ответ может иметь, может не иметь.
- POST - Создание сущности. А так же ситуации когда другие запросы не подошли. В ответ зачастую приходят основные поля сущности | Тело: Запрос может иметь, может не иметь, Ответ: может иметь, может не иметь
- PUT - Обновить сущность, в теле указываются обновляемые поля | Тело: Запрос - должен иметь, Ответ: должен иметь(обновленная сущность с такими же полями как при POST)
- DELETE - Удалить сущность | Тело: запрос - не имеет, ответ - может иметь, но если все хорошо - не имеет
- OPTIONS - Вернет в заголовках список методов которыми можно обращаться к этому url. Нужно для реализации крос-доменных запросов в браузерах. Для mobile-разработки не нужен.
Могут так же использоваться глаголы: (но это на будущее, пока что не используются)
- HEAD - Получить данные, то же самое что GET, но без тела. | безопасный | Тело: Запрос не имеет. Ответ не имеет.
- PUTCH - обновить без замены
- LINK - установить связь между сущностями
- UNLINK - разорвать связь между сущностями
Экшен - это действие которое выполняется над сущность.
Примеры основных экшенов для пользователя
экшен | метод | url | описание |
---|---|---|---|
index | GET | /users | Получить список все(или отфильтрованных) пользователей |
view | GET | /users/4 | Получить одного пользователя |
create | POST | /users | Создать пользователя(регистрация) |
update | PUT | /users/4 | Обновить одного пользователя |
delete | DELETE | /users/4 | Удалить одного пользователя |
Примеры дополнительных экшенов
экшен | метод | url | описание |
---|---|---|---|
login | POST | /users/login | Аутентификация. Пример тела: login=admin&password=123321 . Пример ответа {id: ...(id пользователя), token:...(bearer token)}
|
logout | POST | /users/logout | Выйти. Должен удалится token под которым пользователь послал этот запрос |
Примеры основных экшенов для статьи
экшен | метод | url | описание |
---|---|---|---|
index | GET | /users/4/articles | Получить список статей принадлежащих пользователю id:4 |
index | GET | /users/0/articles | Получить список ВСЕХ статей. Возможно с фильтрами(в query параметрах) |
view | GET | /users/0/articles/5 | Получить статью в id:5 |
create | POST | /users/4/articles | Создать статью принадлежащую 4-му пользователю |
update | PUT | /users/0/articles/5 | Обновить статью с id:5 |
delete | DELETE | /users/0/articles/5 | Удалить статью 5 |
Формат тела запроса ОБЯЗАТЕЛЬНО должен быть указан в заголовке Content-Type
Термины:
-
Сущность
- JSON объект. Возвращается когда есть запрос на обработку конкретного элемента (к примеру/users/5
) -
Коллекция
- Массив сущностей.
Тело запроса должно быть в формате:
-
json
- Content-Type: application/json -
x-www-form-urlencode
- Content-Type: application/x-www-form-urlencoded -
multipart/form-data
- Content-Type: multipart/form-data -
xml
(по умолчанию отключен) - Content-Type: text/xml
Формат ответа. Клиент может запросить ответ в одном из определенных форматов, но указываться клиентом в заголовке Accept
.
- json -
application/json
- xml -
text/xml
Если в ответе если приходит сущность, она ни во что не вложена. Никаких { data: ..., errors: ...}
Поля ответа бывают
-
Основные - это поля которые приходят по умолчанию. Можно запросить что бы они приходили не все, а только часть из них. Для этого нужно в query-параметре
fields
перечислить нужные поля через запятую. Пример?fields=name,surname,avatar
-
Дополнительные - Это поля которые по умолчанию не приходя. Зачастую вычисление значений этих полей требует дополнительных ресурсов, или они имеют объемное значение. По этому они и не приходят по умолчанию. Их можно запросить query-параметром:
?expand=article_count,text
.
Рекомендации по запросу полей:
- Используйте на максимум параметр
fields
. Особенно на часто выполняемых запросах. Если у сущности 20 полей, а вам реально нужно только 3. То указание вfields
только три этих поля - позволит значительно сэкономить трафик, и быстрее получить ответ сервера, что ускорит общую работу приложения. - Не используйте без надобности дополнительные поля (
expand
). Это может привести к перегрузке сервера.
У любой коллекции есть пагинация. Всегда будут заголовки пагинации:
X-Pagination-Total-Count: 1000 - общее кол-во элементов
X-Pagination-Page-Count: 50 - кол-во страниц
X-Pagination-Current-Page: 1 - текущая страница
X-Pagination-Per-Page: 20 - Кол-во на странцу
Link: <http://localhost/users?page=1>; rel=self,
<http://localhost/users?page=2>; rel=next,
<http://localhost/users?page=50>; rel=last
Что бы задать параметры пагинации используются get параметры:
-
?per-page=20
- кол-во на страницу -
?page=2
- страницы -
?page-from-id=30
- максимальный номер первичного ключа с которого считать страницы. Этот параметр нужен что бы если между запросами 2 страниц(page) появится новая запись(или удалится), то что бы не пришел дубликат уже полученной(или не появилось дырки в случае удаления).
- Поиск осуществляется экшеном
index
. - Зачастую в коллекциях в которых нужна сортировка, она просто встроена. И не нужно никаких параметров.
- Фильтры поиска задаются через query-параметры
- Параметры сортировки тоже задается через query-параметры. Рекомендуется query-параметр
sort
, если нужна сортировка в обратном порядке - то перед именем поля задается знак минус.
Пример: /users/4/articles?sort=-name&title=домашние+животные
- Сортировка по
name
в обратном порядке - Фильтр статей по автору. ID пользователя равно 4
- Фильтр по названию. Название должно содержать слова 'домашние животные'
Термины:
- Аутентификация - Процесс получения token'a на основе логина и пароля. Другими словами проверка подлинности источника запроса.
- Авторизация - наделение пользователя правами на выполнение определенных действий. Другими словами - предоставление доступа к чему, для пользователя, который предварительно аутентифицирован
- Идентификация - Опознавание пользователя на основе token'a
В случае неудачи вернется статус:
-
401
- не аутентифицирован -
403
- не авторизирован(идентифицирован, но не доступа к этому запросу)
Протокол идентификации: HTTP Bearer token
В кратце: нужно отправить заголовок формата Authorization: Bearer <token>
Где
-
Bearer
- обязательное слово указывающее способ идентификации. -
<token>
- уникальный идентификатор пользователя. Пример token'a:FFFF70it7tzNsHddEiq0BZ0i-OU8S3xV
Язык ответа задается заголовком: Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4
Можно просто: Accept-Language: ru
200: OK. Everything worked as expected.
201: A resource was successfully created in response to a POST request. The Location header contains the URL pointing to the newly created resource.
207: Multistatus
204: The request was handled successfully and the response contains no body content (like a DELETE request).
304: The resource was not modified. You can use the cached version.
400: Bad request. This could be caused by various actions by the user, such as providing invalid JSON data in the request body, providing invalid action parameters, etc.
401: Authentication failed.
403: The authenticated user is not allowed to access the specified API endpoint.
404: The requested resource does not exist.
405: Method not allowed. Please check the Allow header for the allowed HTTP methods.
413: Request Entity Too Large
415: Unsupported media type. The requested content type or version number is invalid.
422: Data validation failed (in response to a POST request, for example). Please check the response body for detailed error messages.
429: Too many requests. The request was rejected due to rate limiting.
500: Internal server error. This could be caused by internal program errors.
- Ошибки валидации имеют статус
422
- Для одного поля всегда вернется только одна ошибка
Формат ответа при ошибках валидации такой:
[
{
"field": "Название поля в котором ошибка",
"message": "Локализованный текст ошибки"
},
{
... другая ошибка ...
}
]
По вопросам и предложениям обращаться в issuse