Иерархический RESTful URL дизайн

#web-services #rest

#веб-службы #rest

Вопрос:

Я просмотрел вопросы, заданные по этому поводу, но у меня все еще нет окончательного ответа.

У меня есть приложение, и я хотел бы создать RESTful API для предоставления подмножества информации. У меня есть три ресурса:

  1. Пользователи
  2. отчеты
  3. Фото

У пользователей есть отчеты, а в отчетах есть фотографии. Фотографии не могут существовать вне отчетов, а отчеты не могут существовать вне пользователей.

Я разработал следующие URL-адреса для своих требований

При входе пользователя в систему сервер отвечает токеном, который отправляется в заголовке всех вызовов API

 GET example.com/api/
  

Получить информацию о пользователе

 GET example.com/api/users/{username}
  

Получить все пользовательские отчеты

 GET example.com/api/users/{username}/reports
  

Получить все фотографии отчета

 GET example.com/api/users/{username}/reports/{report_id}/photos
  

Добавить фотографию

 POST example.com/api/users/{username}/reports/{report_id}/photos
  

Удалить фотографию

 DELETE example.com/api/users/{username}/reports/{report_id}/photos/{photo_id}
  

Изменить описание фотографии

 PUT example.com/api/users/{username}/reports/{report_id}/photos/{photo_id}
  

Вопросы

  1. Рекомендуется ли добавлять идентификатор ресурса в URL-адрес, т. Е. resource / id, или это должно быть добавлено в качестве параметра запроса?
  2. Является ли этот метод объединения ресурсов в цепочки, т. Е. resource / id / sub-resource / id / etc., приемлемым и хорошим, или я должен поместить все свои ресурсы на верхний уровень и указать его позицию с параметрами запроса?

Комментарии:

1. Мне нравится то, что у вас есть, но мне любопытно, почему вы не рассматриваете фотографии и отчеты как ресурсы верхнего уровня. например, /reports/{reportid}/authors /reports/{reportid}/photos /photos/{photoid}/authors /photos/{photoid}/отчеты. Я понимаю ваши ограничения, но просто любопытно, почему вы не хотели бы углубляться в данные из разных точек входа. Что, если у отчета более одного автора — что, если у вас есть идентификатор или заголовок отчета, Но нет его авторов и т. Д. Нет причин, по которым у вас не может быть нескольких путей к одному и тому же ресурсу, но я бы рекомендовал информировать пользователя о каноническом URI для каждого, если вы это сделаете.

2. Примечание: Restful API всегда должны быть версионными ( example.com/api/… vs example.com/api/1/… ), чтобы избежать столкновений URI с будущими изменениями API .

Ответ №1:

В этом дизайне нет ничего плохого.Но это создает длинные URL, которые иногда трудно понять, и пользователь API должен знать иерархию.Кроме того, потребителю API необходимо написать больше кода немного нестандартным способом (хотя это можно сделать, но будет немного грязно). Подумайте об этом с другой точки зрения: у вас есть три ресурса, и каждый из них имеет свой собственный идентификатор.Итак, если мы реорганизуем вышеуказанные URI, это будет выглядеть так, как показано ниже (я демонстрирую только GET)

Пользовательский ресурс:

Получить список пользователей

   GET example.com/api/users
  

Получить конкретного пользователя

   GET example.com/api/users/{username}
  

Ресурс отчета:

Получить все отчеты

  GET example.com/api/reports
  

Получить конкретный отчет

  GET example.com/api/reports/{report_id}
  

Фоторесурсы

Все фотографии

 GET example.com/api/photos
  

Конкретная фотография

 GET example.com/api/photos/{photo_id}
  

Пользователь Все отчеты

 GET example.com/api/reports?username={userName}
  

Конкретный отчет пользователя

 GET example.com/api/report?username={userName}amp;report_id={reportId}
  

Пользователь Все фотографии

 GET example.com/api/photos?username={userName}
  

Используйте все фотографии для идентификатора отчета (вам может не понадобиться имя пользователя, если report_id уникален независимо от пользователя, что еще больше упростит URI)

 GET example.com/api/photos?username={userName}amp;report_id={reportId}
  

Все фотографии отчета

 GET example.com/api/photos?report_id={reportId}
  

Это упрощает понимание, и с помощью этого подхода на стороне потребителя может быть написано больше стандартного кода.

Комментарии:

1. Мне нравится ваш пример. Если я хочу добавить фотографию, правильно ли передавать идентификатор родителя (пользователя) в теле json? пример сообщения example.com/api/photos { «id»: «user_id_111», «photo»:»my_photo»}

Ответ №2:

ИМХО, вы хорошо его моделируете.

Что касается 1 , я бы resource/id предпочел использовать параметр запроса, а не параметр запроса. Но одна вещь, которую вы должны иметь в виду при моделировании, — это механизм кэширования через прокси и так далее. Поэтому не забывайте о заголовках.

Я использую параметры запроса для фильтрации и тому подобного.

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

Ответ №3:

Я не вижу ничего плохого в вашей схеме.

В настоящее время большинство фреймворков используют аналогичный стандарт для указания URL-адресов (например, Django).

По моему личному мнению, это делает URL более читаемым и немного более приятным для пользователя.