REST Web Services API Design - PullRequest
       13

REST Web Services API Design

15 голосов
/ 20 января 2010

Просто хотел получить отзыв о том, как я планирую создавать свой API. Манекен методы ниже. Вот структура:

GET http://api.domain.com/1/users/ <-- returns a list of users
POST http://api.domain.com/1/users/add.xml <-- adds user
POST http://api.domain.com/1/users/update.xml <-- updates user
DELETE (or POST?) http://api.domain.com/1/users/delete.xml <-- deletes user

Вопросы:

  1. Можно ли использовать только GET и POST?
  2. Это хорошая идея, что я планирую полагаться на имя файла, чтобы указать, какую операцию нужно сделать (например, add.xml для добавления)? Было бы лучше сделать что-то вроде этого: POST http://api.domain.com/1/users/add/data.xml?
  3. Какой хороший способ сохранить версии этих ресурсов? В моем примере я использую / 1 / после имени домена, чтобы указать версию 1. Альтернативы будут: http://api1.domain.com... или http://api -1.domain.com ... или http://apiv1.domain.com... или http://api -v1.domain.com ... или http://api.domain.com/v1/... или
  4. Какой лучший способ аутентификации?

Ответы [ 4 ]

39 голосов
/ 25 января 2010

Прежде чем углубиться в REST, вот несколько терминов, которые вам действительно нужно понять:

Ресурс - вещи / данные, которые вы хотите сделать доступными в вашем API (в вашем случае «Пользователь»)

URI - универсальный уникальный идентификатор для ресурса . Не должно упоминать ничего о выполняемом методе (например, не должно содержать «добавить» или «удалить»). Однако структура вашего URI не делает ваше приложение более или менее RESTful - это распространенное заблуждение.

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

Самая неприятная вещь о ваших URI, какими они сейчас являются, заключается в том, что они имеют информацию о выполняемой операции прямо в них. URI - это идентификаторы и ничего более!

Давайте рассмотрим пример из реального мира. Меня зовут Натан. «Натан» может считаться моим идентификатором (или, в спокойном смысле, URI - для целей этого примера предположим, что я единственный «Натан»). Мое имя / ID не меняются в зависимости от того, как вы хотите со мной взаимодействовать, например, Мое имя не изменится на «NathanSayHello», когда ты захочешь меня приветствовать.

То же самое для отдыха. Ваш пользователь, обозначенный http://api.domain.com/users/1, не изменится на http://api.domain.com/users/1/update.xml, если вы хотите обновить этого пользователя. Тот факт, что вы хотите обновить этого пользователя, подразумевается методом, который вы используете (например, PUT).

Вот мое предложение для ваших URI

# Retrieve info about a user 
GET http://api.domain.com/user/<id>

# Retrieve set all users
GET http://api.domain.com/users

# Update the user IDed by api.domain.com/user/<id>
PUT http://api.domain.com/user/<id>

# Create a new user.  The details (even <id>) are based as the body of the request
POST http://api.domain.com/users

# Delete the user ID'd by api.domain.com/user/<id>
DELETE http://api.domain.com/user/<id>

Что касается ваших вопросов:

  1. Используйте при необходимости PUT и DELETE и избегайте перегрузки POST для обработки этих функций, поскольку это нарушает HTTP-определение POST . HTTP ваш единый интерфейс. Это ваш контракт с пользователем API о том, как они могут ожидать взаимодействия с вашим сервисом. Если вы нарушаете HTTP, вы нарушаете этот контракт.

  2. Удалить "добавить" в целом. Используйте заголовок HTTP Content-Type для указания типа mime публикуемых данных.

  3. Вы имеете в виду версию своего API или версию ресурса? ETag и другие заголовки ответа могут использоваться для версий ресурсов.

  4. Здесь много вариантов. Базовая HTTP-аутентификация (простая, но небезопасная), Digest Auth, настраиваемая аутентификация, такая как AWS. OAuth также возможен. Если безопасность имеет первостепенное значение, я использую клиентские SSL-сертификаты.

7 голосов
/ 20 января 2010

1) По вашему дизайну наверное нет. ПОСТ не идемпотент! Таким образом, вы не должны использовать для обновления или удаления, вместо этого используйте PUT и DELETE из Rest

2) Лучше выбрать заголовок Content-Type при вызове WS, например: application / xml

3) Также в заголовке Content-Type вы можете использовать его: application-v1.0 / xml

4) Не уверен, что это лучший, но, вероятно, самый простой способ - использовать встроенные в HTTP механизмы аутентификации в RFC 2617 Пример: Аутентификация AWS

0 голосов
/ 20 января 2010

Я сделал аутентификацию на основе заголовков. Что-то вроде

X-Username:happy-hamster
X-Password:notmyactualpassword

Если вы беспокоитесь о безопасности - делайте это через SSL. Конечно, существуют и другие реализации. Например, Amazon с их S3: http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTAuthentication.html

Если у вас нет возможности отправлять запросы PUT и DELETE, рекомендуется выполнять туннелирование через POST. В этом случае действие указывается в URL. Если я правильно помню, RoR делает именно это:

POST http://example.com/foos/2.xml/delete

или

POST http://example.com/foos/3.xml/put

...

<foo>
    <bar>newbar</bar>       
</foo>

Это немного оффтоп, но в отношении управления версиями и REST в целом вы можете взглянуть на CouchDB . Вот хорошая книга, доступная онлайн

0 голосов
/ 20 января 2010
  1. В REST HTTP-глагол используется для обозначения типа операции: вы не сможете выразить все операции CRUD только с "GET" и "POST"

  2. нет: в URL ресурса обычно указывается «идентификатор документа»

  3. Версия «документа» может быть передана в заголовке HTTP-ответа при создании / модификации указанного ресурса. Обязанностью сервера является уникальная идентификация ресурсов - попытка сделать это на стороне клиента может оказаться сложной задачей, то есть сохранить согласованность.

Конечно, есть много вариантов по теме ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...