REST URI convention-единственное или множественное имя ресурса при его создании
Я новичок в REST, и я заметил, что в некоторых службах RESTful они используют разные URI ресурсов для обновления/получения/удаления и создания. Например,
- Create-using /ресурсов С помощью метода POST (соблюдайте множественное число) в некоторых местах с помощью /ресурсов (единственное)
- обновление - с помощью / resource / 123 С методом PUT
- Get-Using / resource / 123 С GET method
Я немного запутался в этом соглашении об именовании URI. Что мы должны использовать множественное или единственное число для создания ресурсов? Какими должны быть критерии при принятии такого решения?
18 ответов:
помещения, используя
/resources
Это то, что он представляет "все" ресурсы. Если вы делаетеGET /resources
, скорее всего, вы вернете всю коллекцию. Отправив сообщение на/resources
, вы добавляете в коллекцию.однако отдельные ресурсы доступны в /resource. Если вы делаете
GET /resource
, скорее всего, вы ошибетесь, так как этот запрос не имеет никакого смысла, тогда как/resource/123
имеет смысл.используя
/resource
вместо/resources
похоже на то, как вы бы сделайте это, если вы работали, скажем, с файловой системой и коллекцией файлов и/resource
это "каталог" с индивидуальным123
,456
файлы в ней.не является правильным или неправильным, идти с тем, что вам больше нравится.
для меня лучше иметь схему, которую вы можете сопоставить непосредственно с кодом (легко автоматизировать), главным образом потому, что код-это то, что будет на обоих концах.
GET /orders <---> orders POST /orders <---> orders.push(data) GET /orders/1 <---> orders[1] PUT /orders/1 <---> orders[1] = data GET /orders/1/lines <---> orders[1].lines POST /orders/1/lines <---> orders[1].lines.push(data)
Я не вижу смысла в этом, и я думаю, что это не лучший дизайн URI. Как пользователь службы RESTful я ожидаю, что ресурс списка будет иметь одно и то же имя независимо от того, обращаюсь ли я к списку или конкретному ресурсу " в " списке. Вы должны использовать одни и те же идентификаторы независимо от того, хотите ли вы использовать ресурс списка или конкретный ресурс.
МН
- простой - все адреса начинаются с одного и того же префикса
- логическое -
orders/
получает индексный список ордеров.- стандартный - наиболее широко принятый стандарт, за которым следует подавляющее большинство публичных и частных API.
например:
GET /resources
- возвращает список ресурсов предметы
POST /resources
- создает один или несколько элементов ресурсов
PUT /resources
- обновления одного или нескольких элементов ресурсов
PATCH /resources
- частично обновляет один или несколько элементов ресурсов
DELETE /resources
- удаляет все элементы ресурсаи для отдельных элементов ресурса:
GET /resources/:id
- возвращает определенный элемент ресурса на основе:id
параметр
POST /resources/:id
- создает один элемент ресурса с заданным идентификатор (требует проверки)
PUT /resources/:id
- обновление определенного элемента ресурса
PATCH /resources/:id
- частично обновляет определенный элемент ресурса
DELETE /resources/:id
- удаляет определенный элемент ресурсовк сторонникам единственного числа, подумайте об этом так: вы бы попросили кого-то для
order
и ожидать одно, или список вещей? Так почему же вы ожидаете, что служба вернет список вещей при вводе/order
?
В то время как наиболее распространенной практикой являются RESTful API, где используются множественные числа, например
/api/resources/123
, есть один частный случай, когда я нахожу использование единственного имени более подходящим/выразительным, чем множественное число имен. Это случай отношений один-к-одному. В частности, если целевой элемент является объектом value(в парадигме Domain-driven-design).допустим, что каждый ресурс имеет один-к-одному
accessLog
который может быть смоделирован как объект значения, т. е. не является сущностью, поэтому нет идентификатора. Он мог бы выражаться как/api/resources/123/accessLog
. Обычные глаголы (POST, PUT, DELETE, GET) будут соответствующим образом выражать намерение, а также тот факт, что отношение действительно один к одному.
особой
удобство Вещи могут иметь неправильные имена во множественном числе. Иногда у них его нет. Но особые имена всегда есть.
например, атрибута типа customeraddress за CustomerAddresses
рассмотрим этот связанный ресурс.
этой
/order/12/orderdetail/12
является более читаемым и логичным, чем/orders/12/orderdetails/4
.Таблицы Базы Данных
ресурс представляет собой объект, подобный таблице базы данных. Он должен иметь логическое единственное имя. Вот это ответ над именами таблиц.
Сопоставление Класс
занятия всегда в единственном числе. Инструменты ORM генерируют таблицы с теми же именами, что и имена классов. Поскольку все больше и больше инструментов используются, сингулярные имена становятся стандартом.
подробнее о дилемма разработчика REST API
Почему бы не следовать распространенной тенденции имен таблиц базы данных, где сингулярная форма является общепринятой? Был там, сделал это ... давайте повторно использовать.
таблица именования дилемма: единственное и множественное число имен
С точки зрения потребителя API конечные точки должны быть предсказуемы так
в идеале...
GET /resources
должен возвращать список ресурсов.GET /resource
должен возвращать код состояния 400 уровня.GET /resources/id/{resourceId}
должен возвращать коллекцию с одного ресурса.GET /resource/id/{resourceId}
возвращает объект ресурса.POST /resources
следует пакетного создания ресурсов.POST /resource
создать ресурс.PUT /resource
обновить объект ресурса.PATCH /resource
должны обновить ресурс, разместив только измененные атрибуты.PATCH /resources
должно ли пакетное обновление ресурсов учитывать только измененные атрибуты.DELETE /resources
следует удалить все ресурсы; просто шучу: 400 код состоянияDELETE /resource/id/{resourceId}
этот подход является наиболее гибким и многофункциональным, но и наиболее трудоемким для развивать. Итак, если вы торопитесь (что всегда происходит с разработкой программного обеспечения), просто назовите свою конечную точку
resource
или множественное числоresources
. Я предпочитаю единственную форму, потому что она дает вам возможность самоанализа и оценки программно, так как не все формы множественного числа заканчиваются на "s".сказав Все это, по какой-то причине наиболее часто используемые практики разработчика выбрали использовать форму множественного числа. Это в конечном счете маршрут, который я выбрал, и если вы посмотрите популярные API, такие как
github
икакие-то критерии для принятия решения могут быть:
- какие временные ограничения?
- какие операции я позволю моим потребителям делать?
- как выглядит полезная нагрузка запроса и результата?
- хочу ли я иметь возможность использовать отражение и анализировать URI в моем коде?
так что это зависит от вас. Просто, что бы вы ни делали, будьте последовательны.
Я удивлен, что так много людей будут переходить на множественное число подножку. При реализации преобразований единственного числа во множественное число вы заботитесь о неправильных существительных множественного числа? Вам нравится боль?
посмотреть http://web2.uvcs.uvic.ca/elc/studyzone/330/grammar/irrplu.htm
есть много типов неправильного множественного числа, но это наиболее распространенные:
тип существительного, образующий множественный пример
заканчивается на-fe изменение f до v затем Добавить-s нож ножи жизнь жизнь жена жены Заканчивается-f изменение f на v затем Добавить -Эс половину половинки волк волки буханки хлеба Заканчивается с-o Add-es картофель Картофель помидоры Помидоры вулкан вулканы заканчивается -мы изменяем -нам -я кактус кактусы ядро ядра фокус фокусы заканчивается анализом-is Change-is to-es кризисные кризисы тезисы диссертации заканчивается С-на изменение-на-явление явления критерий критерии Все виды изменяют гласный звук или Изменить слово или Добавить другой конец человек мужчины ступни ног детей человек зубные зубы мышь Неизменное единственное и множественное число такие же овцы олень рыба (иногда)
Я предпочитаю использовать единственную форму для простоты и согласованности.
например, учитывая следующий url:
/ customer / 1
Я буду рассматривать клиента как коллекцию клиентов, но для простоты часть коллекции удаляется.
еще пример:
/оборудования/1
в этом случае оборудование не является правильной формой множественного числа. Так обрабатывать его как собрание оборудования и извлекать собрание для простоты делает его совместимым с делом клиента.
мои два цента: методы, которые тратят свое время на изменение от множественного числа до единственного числа или наоборот, являются пустой тратой циклов процессора. Я, может быть, и старомоден, но в свое время вроде бы вещи назывались одинаково. Как мне искать методы, касающиеся людей? Никакая регулярная экспрессия не покроет как человека, так и людей без нежелательных побочных эффектов.
английские множественное число может быть очень произвольным, и они обременяют код без необходимости. Придерживайтесь одного соглашения об именах. Компьютерные языки должны были быть о математической ясности, а не о подражании естественному языку.
С соглашениями об именах обычно безопасно говорить" просто выберите один и придерживайтесь его", что имеет смысл.
однако, после того, как пришлось объяснить отдых многим людям, представляя конечные точки как пути в файловой системе это самый выразительный способ сделать это.
Он не имеет состояния (файлы либо существуют, либо не существуют), иерархический, простой и знакомый - вы уже знаете, как получить доступ к статическим файлам, локально или через http.и в том, что контекст, лингвистические правила могут привести вас только к следующему:
каталог может содержать несколько файлов и/или подкаталогов, и поэтому его имя должны быть во множественном числе.
и мне это нравится.
Хотя, с другой стороны - это ваш каталог, вы можете назвать его "a-resource-or-multiple-resources", если это то, что вы хотите. Это не самое главное.важно то, что если вы поставите файл с именем " 123 " в каталоге с именем "ресурсы" (в результате
/resourceS/123
), то вы не можете ожидать, что он будет доступен через/resource/123
.Не пытайтесь сделать его умнее, чем это должно быть-изменение от множественного числа до синглуара в зависимости от количества ресурсов, к которым вы в настоящее время обращаетесь, может быть эстетически приятным для некоторых, но это не эффективно, и это не имеет смысла в иерархические
Я знаю, что большинство людей находятся между решением, следует ли использовать множественное или единственное число. Проблема, которая не была решена здесь, заключается в том, что клиенту нужно будет знать, какой из них вы используете, и они всегда могут ошибиться. Вот откуда приходит мое предложение.
как насчет обоих? и под этим я подразумеваю использование единственного числа для всего вашего API, а затем создание маршрутов для пересылки запросов, сделанных во множественном числе, в единственную форму. Для пример:
GET /resources = GET /resource GET /resources/1 = GET /resource/1 POST /resources/1 = POST /resource/1 ...
вы получаете картину. Никто не ошибается, минимальные усилия, и клиент всегда будет получать его правильно.
использование множественного числа для всех методов более практично, по крайней мере, в одном аспекте: если вы разрабатываете и тестируете API ресурсов с помощью Postman (или аналогичного инструмента), вам не нужно редактировать URI при переключении с GET to PUT на POST и т. д.
оба представления полезны. Я использовал единственное число для удобства в течение довольно долгого времени, перегиб может быть трудным. Мой опыт разработки строго сингулярных API REST, разработчики, потребляющие конечную точку, не уверены в том, какой может быть форма результата. Теперь я предпочитаю использовать термин, который лучше всего описывает форму ответа.
если все ваши ресурсы находятся на верхнем уровне, то вы можете уйти с сингулярными представлениями. Избегая перегиба является большой выиграть.
если вы делаете какие-либо глубокие ссылки для представления запросов на отношения, то разработчикам, пишущим против вашего API, может помочь более строгое соглашение.
мое соглашение заключается в том, что каждый уровень глубины в URI описывает взаимодействие с родительским ресурсом, а полный URI должен неявно описывать то, что извлекается.
предположим, что у нас есть следующая модель.
interface User { <string>id; <Friend[]>friends; <Manager>user; } interface Friend { <string>id; <User>user; ...<<friendship specific props>> }
если мне нужно предоставить ресурс, который позволяет клиенту получить менеджер конкретного друга конкретного пользователя, может выглядеть примерно так:
GET /users/{id}/friends/{friendId}/manager
ниже приведены еще несколько примеров:
GET /users
- список пользовательских ресурсов в глобальной коллекции пользователейPOST /users
- создание нового пользователя в глобальной коллекции пользователейGET /users/{id}
- извлечение определенного пользователя из глобальных пользователей коллекцияGET /users/{id}/manager
- получить менеджер конкретного пользователяGET /users/{id}/friends
- получить список друзей пользователяGET /users/{id}/friends/{friendId}
- получить конкретного друга пользователяLINK /users/{id}/friends
- добавить Ассоциацию друзей для этого пользователяUNLINK /users/{id}/friends
- удалите Ассоциацию друзей из этого пользователяобратите внимание, как каждый уровень сопоставляется с родителем, на который можно действовать. Использование разных родителей для одного и того же объекта противоречит здравому смыслу. Получение ресурса по адресу
GET /resource/123
не оставляет никаких указаний на то, что создание нового ресурса должно быть сделано вPOST /resources
как насчет:
/resource/
(не/resource
)
/resource/
означает, что это папка содержит что-то под названием "ресурс", это папка "resouce".а также я думаю, что соглашение об именах таблиц базы данных такое же, например, таблица под названием "пользователь" является "пользовательской таблицей", она содержит что-то под названием "пользователь".
для меня множественное число манипулировать коллекция, в то время как сингулярности манипулируют item внутри этой коллекции.
коллекция позволяет методы GET / POST / DELETE
Item позволяет методы GET / PUT / DELETE
пост /студентов добавить нового ученика в школе.
удалить /студентов удалит всех учеников в школе.
удалить /студент/123 удалит ученика 123 из школы.
это может показаться неважным, но некоторые инженеры иногда забываю идентификатор. Если маршрут всегда был множественным и выполнял удаление, вы можете случайно стереть свои данные. В то время как отсутствие идентификатора в единственном числе вернет маршрут 404 не найден.
для дальнейшего расширения примера, если API был предполагается выставить несколько школ, то что-то вроде
удалить / школа / abc / студенты удалит всех учеников в школе
abc
.выбор правильного слова иногда является проблемой сам по себе, но мне нравится поддерживать множественность для коллекции. Е. Г.
cart_items
илиcart/items
чувствует себя хорошо. В отличие от удаленияcart
, удаляет сам объект корзины, а не элементы в корзине ;).
Я предпочитаю использовать оба множественного числа (
/resources
) и сингулярное (/resource/{id}
) потому что я думаю, что он более четко разделяет логику между работой над сбором ресурсов и работой над одним ресурсом.как важный побочный эффект этого, он также может помочь предотвратить неправильное использование API. Например, рассмотрим случай, когда пользователь ошибочно пытается получить ресурс, указав идентификатор в качестве параметра следующим образом:
GET /resources?Id=123
в этом случае, где мы используйте множественную версию, сервер, скорее всего, проигнорирует параметр Id и вернет список всех ресурсов. Если пользователь не будет осторожен, он будет думать, что вызов был успешным и использовать первый ресурс в списке.
С другой стороны, при использовании в единственном виде:
GET /resource?Id=123
сервер, скорее всего, вернет ошибку, потому что идентификатор не указан правильно, и пользователю придется понять, что что-то не так.