2013-10-01 24 views
1

Итак, я много читал о дизайне RESTfull - специально для работы с ресурсами.HasMany RESTfull (или анти-RESTfull) дизайн?

Принимая канонический пример пользователей, Сообщений и Комментарии, с отношениями, как:

Пользователи --- (hasMany) ---> Сообщение --- (hasMany) ---> Комментарий

можно сначала думать, чтобы выставить что-то вроде:

GET /users    GET /posts    GET /comments 
POST /users    POST /posts    POST /comments 
GET /users/id   GET /posts/id   GET /comments/id 
PUT /users/id   PUT /posts/id   PUT /comments/id 
DELETE /users/id   DELETE /posts/id   DELETE /comments/id 

Но, скажем, я хочу, чтобы все Комментарии определенного сообщение сделанные конкретным пользователем . Я должен был бы сделать что-то вроде:

GET /users/id 
    > someUser 
    > var postIds = someUser.posts() 
GET /posts?id=<postIds[0]>&id=<postIds[1]>&... 
    > somePosts 
    > **application user inspects posts to see which one they care about** 
    > var postOfInterest = somePosts[x]; 
    > var postId = postOfInterest.id; 
GET /comments?id=postId 
    > someComments (finally) 

Предположим, что я забочусь только о сообщение или комментарий в контексте его владелицей. Предположим, что другой структурирование ресурса, которое может быть более естественным (или не могут?):

GET /users 
POST /users 
GET /users/id 
PUT /users/id 
DELETE /users/id 

GET /users/id/posts 
POST /users/id/posts 
GET /users/id/posts/id 
PUT /users/id/posts/id 
DELETE /users/id/posts/id 

GET /users/id/posts/id/comments 
POST /users/id/posts/id/comments 
GET /users/id/posts/id/comments/id 
GET /users/id/posts/id/comments/id 
GET /users/id/posts/id/comments/id 

Что для меня, это, вероятно, лучшее представление о том, что эти ресурсы. Тогда все, что мне нужно:

GET /users/id/posts 
    > somePosts 
    > **application user inspects posts to see which one they care about** 
    > var postOfInterest = somePosts[x]; 
    > var postId = postOfInterest.id; 
GET /users/id/posts/postId/comments 
    > someComments 

Это как раз больше похоже навигации файловой системы, чем предыдущий метод, - но я не знаю, если его RESTfull вообще (возможно, это то, что REST пытается избавиться от), потому что для доступа к Комментарии ресурс, мне нужно знать, какой Пользователь и который Должность принадлежит. Но первый требует 3 запросов, а для последнего требуется всего 2.

Мысли?

+0

Возможный дубликат [Как я должен работать с иерархиями объектов в RESTful API?] (http://stackoverflow.com/questions/3867344/ how-should-i-deal-with-object-hierarchies-in-a-rest-api) – EkoostikMartin

+0

ссылается на этот http://stackoverflow.com/questions/19033462/simple-rest-url-scheme. Посмотрите, помогает ли это. аналогичный вопрос – Satish

ответ

1

Немного о том, что хорошо ОТДЫХ - это мнение, но я бы сказал, что ваш второй подход, как правило, более «RESTful».

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

+0

Да, это то, о чем я обычно думал. Было бы совершенно зло с последним подходом в целом, но выставлять * удобные * маршруты, такие как прямые '/ posts', когда я только забочусь о данных в * Post *, а не о том, кому это принадлежит? – Colin

1

В вашем втором примере это важно иметь какGET /users/id и GET /users/id/posts так, что, когда запрос информации пользователя сделан он не включает в себя все это сообщения (или их идентификаторы) тоже. И второй запрос также вернет свои сообщения. Часто пользователи имеют тысячи сообщений на форуме.

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

Я бы лично пойти с этим вариантом запросов

GET user 
GET post 
GET comment 
... 

для каждого запроса я бы реализовать пункт where, который даст пользователю о моей апи больше возможностей, чтобы сделать конкретный выбор. Например, GET posts where userId='myID'. Он может быть реализован с url query parameters как http://myapi.mydomain.com/post?userId=user1 или внутри заголовка. Он вернет список сообщений для этого пользователя. Вы также можете указать where пункт для ID сообщения - http://myapi.mydomain.com/post?id=123, который вернет только этот пост. Обратите внимание, что в первом случае - при получении списка сообщений вы можете возвращать только какую-то короткую информацию для сообщений (например, id, author, summary ...) и потребовать дополнительный запрос post?id=id для получения полного сообщения ,

Имея эту реализацию даст вам, по крайней мере два преимущества:

  • пользователь API должен знать только один идентификатор, чтобы получить некоторую информацию - сообщения дан, чтобы получить к данному сообщению контента/комментарии, идентификатор пользователя, чтобы получить все сообщения/комментарии для этого пользователя
  • выбора делается на сервере, менее данные передаются по сети, означающей более быстрое реагирование (и потенциально меньше затрат для конечных пользователей, если они находятся на мобильный плане или что-то)

По-моему это им (user, post, comment) и более гибкие запросы

+0

Да, это альтернатива. Я полностью согласен с тем, что это дает мне слабосвязанные объекты с более гибкими запросами - никаких аргументов нет. Но что, если мои ресурсы обязательно связаны, со строгим * владением *? В моем случае иерархия «идет» по мере того, как пользователи ищут листовые узлы в иерархии - с ленивыми данными. То есть, если я делаю запрос на ресурс на глубине N, тогда обязательно должны были быть запросы для владельцев ресурсов на глубинах N-1, N-2, ..., 1 – Colin

+0

Вещь REST не ООП. Это больше похоже на обычные веб-страницы с множеством разных видов. Это 'комментарий' в контексте' post' ('/ post/{pid}/comment/{cid}') отличается от ('/ comment/{cid}'). Поэтому, хотя я ценю @ stan0 ответ ради DRYness, его больше RPC, чем RESTful (IMHO). –

Смежные вопросы