Правила REST: как быть RESTful в HTTP/JSON APIs

0
3852
views

 

Andrew Oliver, разработчик со стажем, опубликовал статью, в которой описывает 7 техник Sass, позволяющие писать код лучше. Редакция techrocks.ru публикует адаптированный перевод материала.


Очень легко быть небрежным при написании API, поэтому ниже объясняется как быть RESTful в клиентских скриптах

Правила для REST: как быть RESTful в API HTTP / JSON

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

Если я отправляю в http://localhost:8983/solr/my_collection/update/json/docs JSON документ {«id»: «1»,»title»: «Doc 1»}, он оказывается явно где-то не тут: http://localhost:8983/solr/my_collection/update/json/docs/1

Solr, по существу, это поисковой движок. Solr имеет HTTP/JSON-based API. Однако это не совсем REST API, потому что он не следует никаким правилам четко определенного REST интерфейса. Иногда я жалуюсь на это. Может быть однажды если у меня будет время, и я это пофикшу. (Я работаю в Lucidworks, которая делает большинство разработки для Solr).

Но опыт в написании скриптов подсказал мне, что правила REST (guidelines) существуют для вашей защиты. Эти правила позволяют очень легко написать API и делают поведение API предсказуемым. Если вы действительно следуете этим правилам, вы очень легко впоследствии сможете этот API использовать.

Вот основные положения:

  1. HTTP GETдолжен быть использован только для извлечения (retrieval). Он никогда не должен использоваться для создания, обновления или чего-то еще.
  2. HTTP POSTдолжен использоваться для создания (creating). Он не должен использоваться для обновления или получения данных. Если URI до этого не было и вы собираетесь его создать и сделать так, чтобы он содержал данные, используйте POST.
  3. HTTP PUTдолжен использоваться для обновления (updating) — что значит заполнение (replacing). URI должен уже существовать.
  4. HTTP DELETEдолжен использоваться для удаления (deleting).

Исходя из этих основных положений:

  1. HTTP GETникогда не должен ничего создавать или иметь какие-то побочные эффекты. GETs может быть закэширован, поэтому ваша система должна с этим как-то обходиться.
  2. HTTP POSTне должен никогда использоваться для массового получения либо обновления.
  3. Если выотсылаете (POST) что-то в URL, вы должны иметь возможность получить (GET) то, что вы выслали, из этого URL. Если это коллекция, вы должны иметь возможность получить (GET) ее из подконтекста этого URL. Например:

curl -X POST —header «Content-Type: application/json» -d ‘[{«id»:»1″, «name»:»Don Draper»}, {«id»:»2″,»name»:»Betty Draper»}, {«3″:»Joan Holloway»}]’ http://localhost/myservice/characters должна позволять curl http://localhost/myservice/characters возвратить целый массив, но curl http://localhost/myservice/characters/1 должна возвращать только {«id»:»1″, «name»:»Don Draper»}. DELETE должна работать таким же образом, чтобы работать с коллекцией или элементом.

  1. Никогда не используйте глаголы в URL, например/addNew.
  2. ИспользуйтеPOST для добавления. Но есть один момент, который нужно иметь в виду: Что если ваша коллекция состоит из 1000 элементов и вы хотите добавить 500, но не хотите перезаписывать 1000? Но в общем случае, просто используйте POST.

Как результат, 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.”

Если вы позволяете клиенту определять ‘сколько’ или фильтровать результаты, это должно быть сделано через параметры строк запроса. Например: ?page=1 or ?q=»name:*Draper». Это не должно наследоваться в вашем API. Это нормально защитить клиента с использованием ошибок, если он, например, запрашивает целую коллекцию и эта коллекция содержит миллион строк.

И наконец, подумайте о будущем. Рассматривайте явное версионирование, как например http://localhost/myservice/v1/character , так что когда вы что-то сломали и у вас новая версия API, вы можете либо быть обратно-совместимым или выдавать ошибку и предупреждать клиента, почему oн больше не может зайти.

И в заключение, ваш API не должен выглядеть как убогий Twitter “REST” API.


ОСТАВЬТЕ ОТВЕТ

Please enter your comment!
Please enter your name here