Назад в библиотеку

Важные аспекты RESTful API для вашего проекта

Автор: Кислицин А.А.

Введение

Данная статья давно назревала в моей голове, но совсем в ином формате. Прочитав последние несколько неуклюжих статей на тему WEB-сервисов (например: http://habrahabr.ru/blogs/development/108973/) и применения в них REST технологии, решил что настало время все-таки откинуть лень, выделить время и написать «переформатированную» в своей голове статью. Итак, кратко, что Вы найдете в статье и кому она будет полезна:

  1. общая идеология REST
  2. Применение CRUD в WEB-сервисах
  3. Принципы KISS при построении раутеров
  4. Лучшие практики
  5. Список ссылок

С чего начать решать вам, я порекомендую сперва дочитать статью, затем еще немного погуглить, выпить чашечку чаю/кофе/нужное_подчеркнуть, разложить мысли по полочкам и затем приступать к созданию вашего эй-пи-ай.

ОБЩАЯ ИДЕОЛОГИЯ

Что же такое REST *(1)?

REST — это “Representational State Transfer”, другими словами — представление данных в удобном для клиента формате, под клиентом мы подразумеваем клиентское ПО из модели client <-> server. В свою очередь веб-сервисы созданные с использованием протокола HTTP и принципов REST называются RESTful web service.

У непосвященного сразу же может возникнуть вопрос: зачем нужны подобные сервисы? Приведу простой пример на основе REST и OAuth технологий: у Вас есть аккаунт на gmail и аккаунт на dropbox. Дропбокс предлагает Вам дополнительное место за каждого приглашенного друга, однако писать письмо вручную и перебирать все адреса из адресной книги gmail — не просто нудно, но и долго. Дропбокс предлагает «давай, дружище, я сам импортирую контакты и разошлю приглашения». Понятное дело, что никто из Вас не захочет давать свой пароль от ящика на гмыле дропбоксу. Тут в силу вступает «магия» RESTful веб-сервисов. Используя API (эй-пи-ай, а не «апи», как многие привыкли произносить), дропбокс делает запрос к веб-сервису гугля, затем отправляет Вас на страницу авторизации гугля, таким образом вы вводите свой пароль в форме у гугла, гугл вас авторизует и дает знать (выдает access_token) дропбоксу об успешности auth-процесса (authentication). В конце концов, имея уникальный токен (access_token) и прикрепляя его к каждому запросу в API, дропбокс имеет возможность работать с Вашими персональными данными, не зная ничего ровным счетом о Вашем пароле.

Важно помнить, что REST — это не обязательно использование протокола HTTP, хотя и изначально архитектура разрабатывалась с применением именно HTTP. В REST может использоваться любой протокол прикладного уровня (application layer) для транспортировки данных.

CRUD

При разработке RESTful веб-сервисов важно помнить о методологии CRUD *(2), что в расшифрованном переводе означает: создать-прочитать-изменить-удалить (create-read-update-delete). Так как разработка веб-сервисов ведется с использованием HTTP протокола, то и использовать нужно его плюшки, а именно: используйте методы протокола для определения действия над ресурсом. В мире REST общеприняты следующие стандарты:

POST — create (создать)
GET — read (прочитать, получить)
PUT — update (изменить, обновить или создать, если не существует, иногда применяется и в таком варианте)
DELETE — delete (удалить)

Необходимо отметить, что PUT и DELETE сложно реализуемые методы и ввиду особенностей браузеров, данным методы реализовать средствами AJAX на стороне клиента-браузера, к тому же еще и чтобы работало во всех браузерах, не представляется возможным. Поэтому принято данные методы использовать посредством перегрузки метода POST. Другими словами: Вы отправляете с POST-методом какую-нибуть зарезервированную переменную, например: http_method, с именем метода, который Вы перегружаете. POST + http_method=put — дает понять вашей серверной части, что клиент запросил PUT над ресурсом.

ПРИНЦИПЫ KISS ПРИ ПОСТРОЕНИИ РАУТЕРА

Для начала расшифруем KISS — keep it small and simple, для тех кто еще не понял — придерживайтесь простых и маленьких вещей, другими словами чтобы это было доступно и понятно каждому и легко запоминалось.

Чтобы получить данные от вашего веб-сервера, клиенту необходимо знать URL, по которому ему необходимо обратиться. О принципах построения этих самых универсальных ресурсных указателей и пойдет речь.

Первым делом определите базовый набор правил, который подходит Вашему сервису. Например, у себя в компании oDesk мы обозначили, что URI, база которых — /api, это ресурсы RESTful API. При желании свой эй-пи-ай, Вы можете вынести на отдельный субдомен, здесь стоит помнить о кросбраузерных запросах и других подводных камнях, которые Вам встретятся, даже при запросах внутри одного домена.

Следующим моментом будет создание раутера ресурса — адреса, по которому можно будет обратиться к данным. Отметим несколько моментов, которые считаются хорошей манерой при составлении адреса:

— разбиение на идиоматические группы: mc — message center ресурсы, team — коммандные ресурсы и тд

   например: /api/mc/…

— версионирование

   например: /api/mc/v1/…

— ясное название ресурса, к которому предоставляется доступ

   например: /api/mc/v1/prefs/… — доступ к настройкам мессадж центра

— внесение персистентных данных под URL

   например: /api/mc/v1/prefs/mydevelopersuid

— определение формата ответа: либо в названии урл-е раутера, либо в системной переменной

   например: /api/mc/v1/prefs/mydevelopersuid.json — oDesk использует суффикс .json когда требуется ответ в формате JSON, .xml — в формате XML и тд.; /mc/v1/prefs/mydevelopersuid?tqx=out:json — так делает Гугль, в GDS; /api/json/mc/v1/prefs/mydevelopersuid — просто еще один возможный вариант, формат является частью раутера.

ЛУЧШИЕ ПРАКТИКИ

Здесь можно много и долго говорить, перечислю основные моменты:

— всегда предоставляйте возможность получения ответа в формате json. Так случилось, что в мире AJAX приложений JSON *(3) стал де-факто стандартом передачи данных между клиентской и серверной частью.

— используйте для авторизации проверенные и отработанные схемы

Не изобретайте свой самокат с использованием md5 подписей данных и прочего, доверьтесь профессионалам в области защиты данных. OAuth придумали за Вас, для него полно библиотек на разных языках — используйте эту мощь. Не хотите OAuth, попробуйте APIKeys как это реализовано у Flickr-а. Есть еще парочка вариантов — OpenID и другие, всех рассматривать не буду — суть я донес.

— не забывайте о https, там где это нужно

и, пожалуйста, не забывайте к документации к своему эй-пи-ай указывать, что ваш сертификат самописный, если он таковым является. Цените время коллег из соседнего цеха, чтобы они не искали баги в своих апликухах только потому, что там стоит проверка на валидность сертификата.

— никогда не вываливайте в ответе что-то невнятное: ошибки Вашего веб-сервера, фаталы, проблемы соединения с базой и тд. Все это должно обрабатываться Вашим RESTful веб-сервером и отдавать внятный ответ в запрошенном формате. Другими словами, предоставьте внятный error responding клиенту. Формат ответа и заголовки — это отдельная тема. Хорошей практикой считается отдача корректных HTTP статусов в соответствии с RFC 2616 *(4) и если статус позволяет отдавать тело сообщения — наличие краткого сообщения в теле. Некоторые предпочитают отдавать всегда статус 200 OK с телом, таким образом клиент должен всегда парсить сообщение и проверять тело на наличие в нем сообщения/тега об ошибке. Однозначной практики и общего мнения пока нет!

— пишите документацию к своему API, иначе эй-пи-ай безполезно :)

— и, наконец, изначально продумайте внутреннюю архитектуру RESTful веб-сервиса, логика должна быть едина для любого запрошенного формата, а преобразование данных должно производится для каждого формата отдельно. Это позволит Вам легко и быстро расширять Ваши раутеры при необходимости добавить новый стандарт отображения данных.

Список ссылок

1. http://en.wikipedia.org/wiki/Representational_State_Transfer
2. http://en.wikipedia.org/wiki/Create,_read,_update_and_delete
3. http://en.wikipedia.org/wiki/JSON
4. http://www.w3.org/Protocols/rfc2616/rfc2616.html
5. http://tech.groups.yahoo.com/group/rest-discuss/