ОТДЫХ Лучшая практика для фильтрации и определения результата в единственном числе: список или один? - PullRequest
0 голосов
/ 26 февраля 2019

Различные практики REST предлагают (то есть 1 , 2 , 3 ) использовать множественное число в ваших конечных точках, и в результате всегда получается список объектов,если оно не отфильтровано по определенному значению, например /users/123 Параметры запроса используются для фильтрации списка, но, тем не менее, приводят к появлению списка.Я хочу знать, должен ли мой случай «отказаться» от этих лучших практик.

Давайте для примера рассмотрим автомобили.
У меня есть база данных, заполненная автомобилями, и каждая из нихимеет BuildNumber («Id»), но также модель и год сборки, комбинация которых уникальна.Если я затем запрашиваю /cars/ и ищу определенную модель и год, например, /cars?model=golf&year=2018, я знаю, что согласно моему предыдущему предложению мое извлечение всегда будет содержать один объект, а не несколько.Тем не менее, мой результат все равно будет списком, содержащим только один объект.

В таком случае, что будет лучшей практикой, так как приведенное выше означало бы, что объект должен быть извлечен из списка, даже если вместо этого мог быть возвращен один объект.

  1. Придерживайтесь лучших практик и экспортируйте список
  2. Создайте вторую конечную точку /car/ и используйте параметры запроса ?model=golf&year=2018, которые в основном используются для фильтрации в списке и в результате получают один объект., как единственная конечная точка заявляет

Причина, по которой я спрашиваю это, заключается просто в чистоте действия: я на 100% уверен, что мой запрос GET приведет к одному объекту,но все равно придется выполнять действия, чтобы извлечь его из списка.Эти шаги должны были быть ненужными.Кроме того, в моем случае я не знаю уникальный идентификатор, поэтому cars/123 для поиска конкретного автомобиля не вариант.Я знаю, однако, фильтры, которые приведут к одному объекту и одному определенному объекту в целом.Дополнительные шаги просто кажутся излишними.


1: https://docs.microsoft.com/en-us/azure/architecture/best-practices/api-design
2: https://blog.mwaysolutions.com/2014/06/05/10-best-practices-for-better-restful-api/
3: https://medium.com/hashmapinc/rest-good-practices-for-api-design-881439796dc9

Ответы [ 3 ]

0 голосов
/ 26 февраля 2019

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

Моя общая мысль об этом заключается в том, что каждый элемент в моей системе будет иметь свойсобственный уникальный URL, например /cars/1234.Этот случай всегда в единственном числе.

Но этот конкретный элемент может отображаться как член в коллекциях и результатах поиска.Когда /cars/1234 появляется в них, они всегда отображаются в виде списка с 1 элементом (или 0 или более в зависимости от запроса).

Я чувствую, что это в конечном итоге наиболее предсказуемо.

Однако в моем случае, если автомобиль отображается как участник поиска или коллекции, его «истинный URL» все равно будет отображаться.

0 голосов
/ 26 февраля 2019

Поскольку вы специально спросили о передовой практике в отношении REST:

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

Кроме того, вам следуетне думать о REST с точки зрения объектной ориентации, а скорее с точки зрения доступности и состояний машины , где клиент получает всю информацию, необходимую для принятия обоснованного решения о том, что делать дальше.

Наилучший пример, который можно привести здесь, - это, вероятно, внимательный взгляд на Интернет и то, как это делается для HTML-страниц.Как вы можете фильтровать для конкретного автомобиля и как он будет представлен вам?Те же самые понятия, которые используются в Интернете, также применяются к REST, поскольку оба используют одну и ту же модель взаимодействия.Что касается образца вашего автомобиля, API должен изначально возвращать некоторые управляющие структуры, которые учат клиента, как должен формироваться запрос и какие параметры могут быть отфильтрованы.В HTML это делается с помощью форм.Для API REST, не основанных на HTML, должны быть определены выделенные медиа-типы, которые переводят тот же подход в структуры, отличные от HTML.При отправке запроса на сервер ваш клиент будет включать все поддерживаемые типы мультимедиа, которые он поддерживает, в заголовок HTTP Accept, который информирует сервер о возможностях клиента.Медиа-типы - это просто читаемая спецификация о том, как обрабатывать полезные нагрузки таких типов.Такие спецификации могут включать подсказки относительно информации о типе, которую может вернуть отношение ссылки .Чтобы получить широкое использование медиа-типов, их следует определить как можно более универсальными.Вместо того, чтобы определять тип носителя, специфичный для автомобиля, что возможно, возможно, было бы удобнее использовать существующий или определить новый общий формат контейнера данных (аналог HTML).

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

К сожалению, ваш вопрос нацелен на нечто совершенно иное, IMO,нечто более связанное с RPC.Вы в основном вызываете универсальный метод через HTTP на конечной точке, подобный работе SOAP, RMI или CORBA.Соблюдаете ли вы семантику HTTP-операций или нет, здесь есть только второстепенный интерес.Даже если вы достигли уровня 3 модели зрелости Ричардсона (RMM) *1019*, это не означает, что вы соответствуете требованиям REST.Ваш клиент может все еще сломаться, если сервер изменяет что-либо в ответе.Кроме того, RMM даже не рассматривает медиа-типы вообще, поэтому я считаю его довольно бесполезным.

Однако, независимо от того, используете ли вы (истинный) клиент REST или RPC / CRUD, если извлечение отдельных элементов являетсявместо того, чтобы вводить их в коллекцию, вы должны рассмотреть возможность включения URI интересующих элементов, а не их данных, непосредственно в коллекцию, как предложил Эверт.Хотя большинство людей, похоже, обеспокоены производительностью сервера и временем прохождения туда-обратно, на самом деле это очень элегантно с точки зрения кэширования.Кроме того, некоторые имена отношений с ссылками, такие как prefetch, могут информировать клиента о том, что он может получить целевую полезную нагрузку на ранней стадии, поскольку весьма вероятно, что ее содержимое будет запрошено следующим.Посредством кэширования запрос может даже не запускаться и не отправляться на сервер для обработки, что, вероятно, является лучшим приростом производительности, которого вы можете достичь.

0 голосов
/ 26 февраля 2019

1) Если вы используете запрос как автомобили / где ... - используйте CARS

2) Если вы хотите CAR - используйте метод GetCarById

...