REST - поддержка нескольких возможных идентификаторов - PullRequest
52 голосов
/ 09 мая 2009

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

/users/48573

А теперь это выглядит как

/users/thisisausername.

Единственная проблема заключается в том, что нам все еще нужно иметь возможность каким-то образом извлекать их через числовые идентификаторы для унаследованных потребителей API. Нам не нужны сами REST-URL для перенаправления (например, /users/48573 не должен перенаправлять на /users/thisisausername), нам просто нужен метод для получения правильных данных с использованием старого идентификатора. Решение должно либо обеспечить альтернативный способ доступа к пользовательской информации (которая обычно включает в себя новый идентификатор, имя пользователя) по идентификатору, либо доступ только к имени пользователя по идентификатору. Некоторые возможные решения могут быть:

  • Использование узла для указания альтернативного метода идентификации, например, /users/byid/48573
  • Использование параметра запроса для указания альтернативного метода идентификации, например, /users/48573?fetchby=id или /users/48573?byid=true
  • Обработка имени пользователя по идентификатору как другого ресурса, например /identifiers/username/48573

Какой из них (если есть) наиболее близок к правильному ОТДЫХУ? Как бы вы справились с проблемой?

Ответы [ 5 ]

31 голосов
/ 16 марта 2012

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

Лично я планирую использовать префикс сегмента пути, разделенный символом "=", например "name =" или "email =":

user/123456
user/name=john.doe
user/email=john.doe@john.doe

Это функционально эквивалентно добавлению сегмента пути (например, "user / name / john.doe"), но мне кажется, что оно более точно соответствует концептуальной модели. Конечно, это незначительная деталь, поскольку RESTful API не должны все равно определять фиксированную структуру URI.

Не использование параметров запроса также позволяет естественным образом получать доступ к подресурсам:

user/name=john.doe/inbox/df87bhJXrg63

Фреймворки, такие как поддержка Java JAX-RS с использованием любого разделителя:

@GET
@Path("user/{id}")
User getUser(@PathParam("id") UUID id);

@GET
@Path("user/name={name}")
User getUserByName(@PathParam("name") String name);

@GET
@Path("user/email={email}")
User getUserByEmail(@PathParam("email") String email);
16 голосов
/ 09 мая 2009

Ваш первый вариант, вероятно, лучший.

Поиск пользователей по ID:

/users/id/48573

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

/users/name/thisisausername

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

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

/users?id=48573
/users?name=thisisausername

Я думаю, что первое выглядит чище и читабельнее.

0 голосов
/ 09 июня 2016

Довольно старый вопрос, но у меня был такой же, и в конце концов я нашел решение: используйте регулярное выражение в вашем параметре пути.

Вот как я кодировал этот вариант использования

@GET
@Path("/{id : \\d+}")
@Produces(APPLICATION_JSON)
public Response getById(@PathParam("id") long id) {
 <<your code>>
}

@GET
@Path("/{name}")
@Produces(APPLICATION_JSON)
public Response getByName(@PathParam("name") String name) {
 <<your code>>
}
0 голосов
/ 20 июля 2009

Ваш API не является RESTful, если это проблема. цитата Рой Филдинг:

REST API не должен определять фиксированные имена ресурсов или иерархии (очевидная связь клиента и сервера). Серверы должны иметь свободу управления своим собственным пространством имен. Вместо этого позвольте серверам инструктировать клиентов о том, как создавать соответствующие URI, например, в HTML-формах и шаблонах URI, определяя эти инструкции в типах мультимедиа и отношениях ссылок. [Ошибка здесь подразумевает, что клиенты принимают структуру ресурса из-за внеполосной информации, такой как специфичный для области стандарт, который является ориентированным на данные эквивалентом функциональной связи RPC].

API REST следует вводить без каких-либо предварительных знаний, кроме начального URI (закладки) и набора стандартизированных типов мультимедиа, подходящих для предполагаемой аудитории (то есть ожидается, что это поймет любой клиент, который может использовать API). С этого момента все переходы состояния приложения должны определяться выбором клиентом предоставленных сервером вариантов, которые присутствуют в полученных представлениях или подразумеваются пользовательскими манипуляциями с этими представлениями. Переходы могут быть определены (или ограничены) знаниями клиента о типах мультимедиа и механизмах обмена ресурсами, которые могут быть улучшены на лету (например, код по запросу). [Ошибка здесь подразумевает, что внешняя информация является движущей силой взаимодействия, а не гипертекста.]

0 голосов
/ 18 мая 2009

Я хотел бы рассмотреть возможность задания строки с необязательным суффиксом:

/users/48573/id

/users/48573/name

Если вы получаете строку без суффикса:

/users/48573

затем вы проверяете строку и смотрите, является ли это идентификатором или именем.

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

/users/48573/id

Если вы возвращаете только имя, тогда поиск по имени эквивалентен:

/users/48573/name

Если вы можете извлечь значение по идентификатору или имени, вы вернете ошибку 300 и вернете клиенту ссылки на обе возможности:

/users/48573/id

/users/48573/name

Устаревшие потребители продолжают работать «как есть», за исключением случайного появления дублирующихся пар ID / имя, когда они получают новую ошибку 300 ответа.

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