REST URI convention-единственное или множественное имя ресурса при его создании


Я новичок в REST, и я заметил, что в некоторых службах RESTful они используют разные URI ресурсов для обновления/получения/удаления и создания. Например,

  • Create-using /ресурсов С помощью метода POST (соблюдайте множественное число) в некоторых местах с помощью /ресурсов (единственное)
  • обновление - с помощью / resource / 123 С методом PUT
  • Get-Using / resource / 123 С GET method

Я немного запутался в этом соглашении об именовании URI. Что мы должны использовать множественное или единственное число для создания ресурсов? Какими должны быть критерии при принятии такого решения?

18 372

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 конечные точки должны быть предсказуемы так

в идеале...

  1. GET /resources должен возвращать список ресурсов.
  2. GET /resource должен возвращать код состояния 400 уровня.
  3. GET /resources/id/{resourceId} должен возвращать коллекцию с одного ресурса.
  4. GET /resource/id/{resourceId} возвращает объект ресурса.
  5. POST /resources следует пакетного создания ресурсов.
  6. POST /resource создать ресурс.
  7. PUT /resource обновить объект ресурса.
  8. PATCH /resource должны обновить ресурс, разместив только измененные атрибуты.
  9. PATCH /resources должно ли пакетное обновление ресурсов учитывать только измененные атрибуты.
  10. DELETE /resources следует удалить все ресурсы; просто шучу: 400 код состояния
  11. DELETE /resource/id/{resourceId}

этот подход является наиболее гибким и многофункциональным, но и наиболее трудоемким для развивать. Итак, если вы торопитесь (что всегда происходит с разработкой программного обеспечения), просто назовите свою конечную точку resource или множественное число resources. Я предпочитаю единственную форму, потому что она дает вам возможность самоанализа и оценки программно, так как не все формы множественного числа заканчиваются на "s".

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

какие-то критерии для принятия решения могут быть:

  1. какие временные ограничения?
  2. какие операции я позволю моим потребителям делать?
  3. как выглядит полезная нагрузка запроса и результата?
  4. хочу ли я иметь возможность использовать отражение и анализировать 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

сервер, скорее всего, вернет ошибку, потому что идентификатор не указан правильно, и пользователю придется понять, что что-то не так.