2. Key requirements for the API
• It should use web standards where they make
sense
• It should be simple, intuitive and consistent
• It should be efficient, while maintaining balance
with the other requirements
3. The key principles of REST involve separating
your API into logical resources.
These resources are manipulated using HTTP
requests where the method (GET, POST,
PUT, PATCH, DELETE) has specific meaning.
4. RESTful principles provide strategies to handle CRUD
actions using HTTP methods mapped as follows:
• GET /tickets - Retrieves a list of tickets
• GET /tickets/12 - Retrieves a specific ticket
• POST /tickets - Creates a new ticket
• PUT /tickets/12 - Updates ticket #12
• PATCH /tickets/12 - Partially updates ticket #12
• DELETE /tickets/12 - Deletes ticket #12
5. There are no method naming
conventions to follow and the URL structure
is clean & clear.
7. • GET /tickets/12/messages - Retrieves list of messages for ticket
#12
• GET /tickets/12/messages/5 - Retrieves message #5 for ticket #12
• POST /tickets/12/messages - Creates a new message in ticket
#12
• PUT /tickets/12/messages/5 - Updates message #5 for ticket #12
• PATCH /tickets/12/messages/5 - Partially updates message #5 for
ticket #12
• DELETE /tickets/12/messages/5 - Deletes message #5 for ticket
#12
9. • An activate action could be mapped to a boolean
activated field and updated via a PATCH to the
resource
• PUT /gists/:id/star and DELETE /gists/:id/star
• Just do what's right from the perspective of the
API consumer and make sure it's documented
clearly
11. Result filtering, sorting &
searching
• GET /tickets?state=open - query parameter that
implements a filter
• GET /tickets?sort=-priority - Retrieves a list of
tickets in descending order of priority
• GET /tickets?q=return&state=open&sort=-
priority,created_at - Retrieve the highest priority
open tickets mentioning the word 'return'
14. An API that accepts JSON encoded POST, PUT & PATCH requests should
also require the Content-Type header be set to application/json or throw a
415 Unsupported Media Type HTTP status code.
JSON encoded POST, PUT & PATCH bodies
16. Rate limiting
• X-Rate-Limit-Limit - The number of allowed
requests in the current period
• X-Rate-Limit-Remaining - The number of
remaining requests in the current period
• X-Rate-Limit-Reset - The number of seconds left
in the current period
18. HTTP status codes
• 200 OK - Response to a successful GET, PUT,
PATCH or DELETE. Can also be used for a
POST that doesn't result in a creation.
• 201 Created - Response to a POST that results
in a creation. Should be combined with a
Location header pointing to the location of the
new resource
• 204 No Content - Response to a successful
request that won't be returning a body (like a
DELETE request)
19. • 400 Bad Request - The request is malformed,
such as if the body does not parse
• 401 Unauthorized - When no or invalid
authentication details are provided. Also useful to
trigger an auth popup if the API is used from a
browser
• 403 Forbidden - When authentication succeeded
but authenticated user doesn't have access to
the resource
20. • 404 Not Found - When a non-existent resource is
requested
• 405 Method Not Allowed - When an HTTP
method is being requested that isn't allowed for
the authenticated user
• 429 Too Many Requests - When a request is
rejected due to rate limiting
Важными, но не вбитыми в стену принципами построения АПИ является
- следование веб стандартам ( там где это имеет смысл)
- простота, интуитивность, целостность
- эффективность при соблюдении баланса с другими принципами
Самое замечательное в использовании http методов то, что вам не нужно использовать в своих адресах названия методов или действий которые вы хотите совершать с ресурсом. Все методы говорят сами за то действие которое должно быть описано в соответствующем эндпоинте.
Ключевым принципом REST является разделение вашего API на ресурсы и использование http методов в соотвествии с действиями, выполняемыми для этих ресурсов.
Ресурсы должны иметь имена существительные, они могут соответствовать моделям в вашей реализации, но это совсем не обязательно.
Например в качестве ресурсов могут быть использованы: ticket, user, group
После того как вы определились с ресурсами, вы должны понять какие действия будут совершаться с этими ресурсами и как они будут соотноситься с вашим API.
RESTful стратегия определяет использование crud действий в качестве следующих http методов
Еще один интересный вопрос использовать ли единственное число, или множественное в обозначении ваших ресурсов. Будьте проще. Простое правило применимо и тут, хотя ваш внутренний грамарнаци возможно скажет что не правильно получать один экземпляр ресурса с использованием множественного числа, но все же что бы сохранить общность лучше всегда использовать множественное число. Это сделает вашу жизнь и жизнь пользователей вашего API значительно проще. К тому же большинство современных фреймворков позволяет удобно реализовать /tickets и /tickets/12 в одном контроллере.
Но как же быть с отношениями ресурсов. Если отношение может существовать только в пределах конкретного ресурса, то и тут REST принципы вполне применимы
Если говорить о загрузке отношений вместе с обьектом, то, к примеру, библиотека franctal предлагает такой подход.Они предлагают описывать доступные для дополнения респонс объекты в качестве подключаемых include которые пользователь вашего api может запросить по собственному желанию, в зависимости от того нужны они ему или нет.
Что же насчет действий, который не вписываются в формат CRUD
Для этого случая существует несколько подходов.
Поменяйте действие так, что бы оно вписывалось в формат ресурса. Это работает для действий, не принимающих параметра. Например действие активации которое может находится только в двух логических состояниях может быть интерпретировано как PATCH к ресурсу.
Относитесь к действию как подресурсу например API гитхаба позволяет добавить и убрать звезду такими запросами
Иногда действительно нет другого способа представить действия в виде отношения к ресурсу. Например поиск по нескольким ресурсам. Это ОК, просто сделайте это удобно и убедитесь что реализация хорошо задокументированна
Несколько пунктов о которых не стоит забывать
Поскольку вашим приложением пользуются совершенно из разных мест мира не плохо бы шифровать ваш трафик и делать все запросы исключительно по https
Документация к вашему апи очень важный аспект написания самого апи, по возможности держите вашу документацию в актуальном состоянии. Своевременно обновляя ее вместе с релизами новых возможностей (или изменений) вашего API. Если вы поддерживаете публичное апи, не забывайте также поддерживать актуальный ченжлог, выписывая туда произошедшие, с API изменения и деприкейтед методы
Версионируйте ваше апи, это поможет быстрее разрабатывать новые фичи, а так же поможет не поломать работу со старыми, но измененными функциями. Есть несколько способов версионирования. Используя URL или header
Вообще говоря эти подходы можно смешивать, добиваясь более гибкой возможности работы с вашим API и возможности более плавного обновления и перехода к новым версиям для ваших пользователей.
Фильтрация, сортировка, поиск
Лучше всего держать ваше API как можно более простым и понятным, однако иногда требуется и получение более сложных, предобработаных результатов. Все эти три пункта могут быть реализованы используя параметры запроса скомпонованные и оформленные разными способами. Один из вариантов как они могут быть оформлены, такой.
Обновление и создание ресурса должны возвращать сам ресурс что бы не требовался повторный запрос данных
Только JSON
если кто-то еще интересовался xml, то кажется пришло время оставить его позади
JSON INPUT
Если вы следуете тому что рассказано ранее, то наверняка вы используете JSON в качестве output формата. Давайте быть последовательны, будем использовать JSON в качестве input формата.
Передача формой может быть уместна когда вы делаете простое API, однако когда на вход должен приходить достаточно большой, комплексный объект, JSON кажется подойдет для этого лучше.
Однако тут вынужден признать что я рассматриваю JSON как самый распространенный формат используемый на текущий момент. Конечно существуют альтернативы такие как BSON, MessagePack и другие. Однако я думаю большинство из нас все же пишет веб. А для веба чаще всего удобно иметь человеко-читаемый формат запросов и ответов, однако если для вас критически важна скорость и компактность конечно стоит посмотреть в их сторону.
Немного холивара если в качестве основного клиента вашего API будет JS то кажется имеет смысл использовать стиль принятый в JS а именно кемелкейс, тоже самое можно сказать если основной ваш клиент на каком-то другом языке то стоит использовать договор этого языка CamelCase для C # и Java, snake_case для Python и Ruby.
Немного наброса на вентилятор. На основании исследования проведенного в 2010 году снейк кейс на 20% легче для чтения чем кемел кейс. Что значит использования снейк-кейса увеличит читаемость вашего апи. Кроме того многие популярные JSON API уже используют снейк кейс
Рейт лимит
Для предотвращения абьюза часто использование апи ( особенно публичных) имеют ограничение на количество запросов. При превышении этого лимита имеет смысл возвращать HTTP status code 429 Too Many Requests
Однако очень полезно с каждым запросом возвращать заголовки, с информацией о том, сколько же осталось до прекращения свободного доступа к данным
Ошибки
Так же как обычные страницы предоставляют подробные описания ошибки, так и АПИ вполне может быть использовано для подробного пояснения что же собственно пошло не так в обработке запроса. Для описания таких ошибок часто используют такой формат.
Вместе с такими ошибками АПИ всегда должно возвращать адекватные коды ответа. Обычно оти коды разделяются на два типа 400е - ошибки обработки данных клиента и 500е - ошибки сервера.