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

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

  • Создать - используя /resources с помощью метода POST (наблюдайте множественное число) в некоторых местах, используя /resource (единственное)
  • Обновление - используя /ресурс/123 с помощью метода PUT
  • Получить - использование /ресурса/123 с помощью метода GET

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

+480
источник поделиться
20 ответов

Предпосылкой использования /resources является то, что он представляет "все" ресурсы. Если вы выполните GET /resources, вы, скорее всего, вернете всю коллекцию. От POST до /resources вы добавляете в коллекцию.

Однако отдельные ресурсы доступны в /resource. Если вы выполните GET /resource, вы, скорее всего, ошибетесь, так как этот запрос не имеет никакого смысла, тогда как /resource/123 имеет смысл.

Использование /resource вместо /resources аналогично тому, как вы это сделали бы, если бы вы работали, скажем, с файловой системой и коллекцией файлов, а /resource - это "каталог" с индивидуальным 123, 456 в нем.

Ни один из способов не является правильным или неправильным, пойдите с тем, что вам больше нравится.

+260
источник

Для меня лучше иметь схему, которую вы можете сопоставить непосредственно с кодом (легко автоматизировать), главным образом потому, что код - это то, что будет на обоих концах.

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) 
+559
источник
другие ответы

Связанные вопросы


Похожие вопросы

Я тоже не вижу смысла в этом, и я думаю, что это не лучший дизайн URI. Являясь пользователем службы RESTful, я ожидал бы, что ресурс списка будет иметь то же имя независимо от того, получаю ли я доступ к списку или конкретному ресурсу в списке. Вы должны использовать те же идентификаторы, независимо от того, хотите ли вы использовать ресурс списка или определенный ресурс.

+260
источник

множественное число

  • Все просто - все URL начинаются с одинакового префикса
  • Логика - 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?

+62
источник

Единственное число

Удобство Вещи могут иметь неправильные имена во множественном числе. Иногда их нет. Но имена в единственном числе всегда есть.

например, CustomerAddress поверх CustomerAddresses

Рассмотрим этот связанный ресурс.

Этот /order/12/orderdetail/12 более /order/12/orderdetail/12 и логичен, чем /orders/12/orderdetails/4.

Таблицы базы данных

Ресурс представляет сущность, подобную таблице базы данных. У него должно быть логическое единственное имя. Здесь ответ на имена таблиц.

Отображение классов

Классы всегда единичны. Инструменты ORM генерируют таблицы с теми же именами, что и имена классов. По мере того, как все больше и больше инструментов используются, единичные имена становятся стандартом.

Узнайте больше о дилемме разработчика REST API

+40
источник

В то время как наиболее распространенной практикой является RESTful apis, где используются множественные числа, например. /api/resources/123, есть один частный случай, когда я нахожу использование особого имени более подходящим/выразительным, чем множественные имена. Это относится к отношениям один-к-одному. В частности, если целевой объект является объектом значения (в парадигме, основанной на домене).

Предположим, что каждый ресурс имеет один-к-одному accessLog, который может быть смоделирован как объект значения, а не объект, поэтому нет идентификатора. Его можно было бы выразить как /api/resources/123/accessLog. Обычные глаголы (POST, PUT, DELETE, GET) надлежащим образом выражают намерение, а также тот факт, что отношения действительно взаимно однозначны.

+29
источник

Почему бы не следовать распространенному тренду имен таблиц базы данных, где единая форма обычно принимается? Был там, сделал это - повторное использование.

Дилемма имен таблиц: сингулярные или множественные имена

+20
источник

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

Видеть http://web2.uvcs.uvic.ca/elc/studyzone/330/grammar/irrplu.htm

Существует много типов нерегулярных множественного числа, но они являются наиболее распространенными:

Тип существительного Формирование множественного числа Пример

Ends with -fe   Change f to v then Add -s   
    knife   knives 
    life   lives 
    wife   wives
Ends with -f    Change f to v then Add -es  
    half   halves 
    wolf   wolves
    loaf   loaves
Ends with -o    Add -es 
    potato   potatoes
    tomato   tomatoes
    volcano   volcanoes
Ends with -us   Change -us to -i    
    cactus   cacti
    nucleus   nuclei
    focus   foci
Ends with -is   Change -is to -es   
    analysis   analyses
    crisis   crises
    thesis   theses
Ends with -on   Change -on to -a    
    phenomenon   phenomena
    criterion   criteria
ALL KINDS   Change the vowel or Change the word or Add a different ending   
     man   men
     foot   feet
     child   children
     person   people
     tooth   teeth
     mouse   mice
 Unchanging Singular and plural are the same    
     sheep deer fish (sometimes)
+14
источник

С точки зрения потребителя 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'.

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

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

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

Так это вам. Просто, что бы вы ни были согласованы.

+13
источник

Мои два цента: методы, которые тратят свое время на переход от множественного числа к единственному или наоборот, являются пустой тратой циклов процессора. Я могу быть старой школой, но в свое время, как и вещи, называли то же самое. Как искать методы, касающиеся людей? Никакое регулярное выражение не будет охватывать как человека, так и людей без нежелательных побочных эффектов.

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

+6
источник

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

Например, учитывая следующий URL:

/клиент/1

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

Другой пример:

/оборудование/1

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

+5
источник

Идентификатор в маршруте должен рассматриваться так же, как индекс для списка, и присвоение имен должно выполняться соответствующим образом.

numbers = [1, 2, 3]

numbers            GET /numbers
numbers[1]         GET /numbers/1
numbers.push(4)    POST /numbers
numbers[1] = 23    UPDATE /numbers/1

Но некоторые ресурсы не используют идентификаторы в своих маршрутах, потому что либо один, либо пользователь никогда не имеет доступа к более чем одному, поэтому это не списки:

GET /dashboard
DELETE /session
POST /login
GET /users/{:id}/profile
UPDATE /users/{:id}/profile
+4
источник

С соглашениями об именах обычно безопасно говорить "просто выбрать один и придерживаться", что имеет смысл.

Однако после объяснения REST для большого количества людей представление конечных точек как путей в файловой системе является наиболее выразительным способом его выполнения. Он является безстоящим (файлы существуют или не существуют), иерархические, простые и знакомые - вы уже знаете, как обращаться к статическим файлам, будь то локально или через http.

И в этом контексте лингвистические правила могут привести только к следующему:

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

И мне это нравится.
Хотя, с другой стороны, это ваш каталог, вы можете назвать его "ресурсом-или-несколькими ресурсами", если это то, что вы хотите. Это не очень важная вещь.

Важно то, что если вы поместите файл под названием "123" под каталогом "resourceS" (в результате получится /resourceS/123), вы не сможете ожидать, что он будет доступен через /resource/123.

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

Примечание. Технически вы можете создавать "символические ссылки", так что /resourceS/123 можно также получить через /resource/123, но первая должна существовать!

+3
источник

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

Как насчет обоих? И под этим я подразумеваю использовать единственное число для всего вашего API, а затем создавать маршруты для пересылки запросов, сделанных во множественном числе, в единственное число. Например:

GET  /resources     =     GET  /resource
GET  /resources/1   =     GET  /resource/1
POST /resources/1   =     POST /resource/1
...

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

+2
источник

Использование множественного числа для всех методов более практично, по крайней мере, в одном аспекте: если вы разрабатываете и тестируете API ресурсов через Postman (или аналогичный инструмент), вам не нужно редактировать URI при переключении с GET на PUT на POST и т.д.

+1
источник

Оба представления полезны. Я использовал сингулярное для удобства в течение некоторого времени, перегиб может быть затруднен. Мой опыт разработки строго особых 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

+1
источник

Посмотрите Google Руководствопо разработке API: имена ресурсов, чтобы ознакомиться с другими ресурсами именования.

Короче говоря:

  • Коллекции названы множественным числом.
  • Отдельные ресурсы именуются со строкой.
|--------------------------+---------------+-------------------+---------------+--------------|
| API Service Name         | Collection ID | Resource ID       | Collection ID | Resource ID  |
|--------------------------+---------------+-------------------+---------------+--------------|
| //mail.googleapis.com    | /users        | /[email protected] | /settings     | /customFrom  |
| //storage.googleapis.com | /buckets      | /bucket-id        | /objects      | /object-id   |
|--------------------------+---------------+-------------------+---------------+--------------|

Стоит прочитать, если вы думаете об этом предмете.

+1
источник

Как насчет:

/resource/ (не /resource)

/resource/ означает, что папка содержит нечто, называемое "ресурс", это папка "resouce".

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

0
источник

Для меня множественное число манипулирует коллекцией, тогда как единственное число манипулирует предметом внутри этой коллекции.

Сбор позволяет методами GET/POST/DELETE

Пункт позволяет методы GET/PUT/DELETE

Например

POST on /ученики добавят нового ученика в школу.

УДАЛИТЬ на /ученики удалят всех учеников в школе.

DELETE on /student/123 удалит ученика 123 из школы.

Это может показаться неважным, но некоторые инженеры иногда забывают идентификатор. Если маршрут всегда был множественным и выполнял УДАЛЕНИЕ, вы можете случайно стереть ваши данные. При отсутствии идентификатора в единственном числе будет возвращен маршрут 404, который не был найден.

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

DELETE on /school/abc/ученики удалит всех учеников из школьной abc.

Выбор правильного слова иногда является проблемой сам по себе, но мне нравится поддерживать множественность для коллекции. Например, cart_items или cart/items чувствует себя хорошо. В отличие от удаления cart, удаляет объект корзины сам, а не элементы в корзине;).

-1
источник

Я предпочитаю использовать как множественное число (/resources), так и единственное (/resource/{id}), потому что я думаю, что он более четко отделяет логику между работой над сбором ресурсов и работой на одном ресурсе.

Как важный побочный эффект этого, он также может помочь предотвратить неверное использование API. Например, рассмотрите случай, когда пользователь ошибочно пытается получить ресурс, указав Id в качестве параметра следующим образом:

GET /resources?Id=123

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

С другой стороны, при использовании сингулярной формы:

GET /resource?Id=123

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

-3
источник

Посмотрите другие вопросы по меткам или Задайте вопрос