Иерархические RESTful URL все еще предпочтительнее - с точки зрения дополнительных накладных расходов - по сравнению с плоскими URL? - PullRequest
4 голосов
/ 07 февраля 2012

Допустим, у меня есть веб-сайт, где пользователи могут загружать и показывать свои фотографии. URL RESTful для одной картинки этого пользователя будет выглядеть так:

http://api.gallery.com/users/{user-id}/images/{image-id}

Но сам идентификатор изображения уже уникален, поэтому этот URL-адрес уже будет достаточно хорош для его получения:

http://api.gallery.com/images/{image-id}

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

Является ли RESTful в таком случае все еще предпочтительным?

Ответы [ 3 ]

8 голосов
/ 07 февраля 2012

Короче, оба предпочтительны;Оба могут возвращать одну и ту же «вещь», но «контекст» различен.

Давайте посмотрим на ваши URL:

  • /users: все пользователи
  • /users/1: пользователь № 1
  • /users/1/images: все изображения пользователя № 1
  • /users/1/images/1: изображение № 1 пользователя № 1

Всевышеупомянутые URL вращаются вокруг "пользовательского" ресурса.Это «все пользователи», «пользователь», «изображения пользователя» и т. Д.

  • /images: все изображения
  • /images/1: изображение # 1

Все вышеперечисленные URL вращаются вокруг ресурса «изображение».Это «все изображения» или «изображение».

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

Например, предположим, что вы хотите получить список всех изображений пользователя # 1, что является предпочтительным?

/users/1/images

или

/images?where=user.id eq 1

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

А что если вы хотите получить список изображений с ассоциированным пользователем?

/users/???

или

/images?include=user

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

Теперь, что касается безопасности, в идеале это должно быть сделано полностью прозрачным для потребителя способом.Потребитель должен иметь возможность сказать «Я хочу все изображения».и только когда-либо получать все изображения, к которым они имеют доступ.Если они пытаются получить доступ к определенному ресурсу, к которому у них нет доступа, должен быть возвращен соответствующий код ошибки HTTP.

1 голос
/ 07 февраля 2012

Я думаю, что все зависит от семантики и намерений.Похоже, вы говорите о защищенном ресурсе, а не о публично доступном.В этом случае ваше сообщение является более явным и вызывает наименьшее количество неожиданностей при использовании более подробного формата:

http://api.gallery.com/users/{user-id}/images/{image-id}

Если это общедоступный ресурс, его можно идентифицировать только по идентификатору изображения, а затемболее короткий формат будет более логичным:

http://api.gallery.com/images/{image-id}
1 голос
/ 07 февраля 2012

Я думаю, что второй более RESTful по той причине, о которой вы говорите. URL является иерархией. Идентификатор пользователя на самом деле не является частью идентификации изображения, так зачем делать его частью идентификатора?

Создайте ресурс / users / {user-id} / images, который возвращает список URL-адресов в форме / images / {image-id}, чтобы перечислить изображения, загруженные пользователем, и у вас есть лучшее из обоих миры.

...