Convenção REST URI - Nome singular ou plural do recurso ao criá-lo

529

Eu sou novo no REST e observei que em alguns serviços RESTful eles usam URI de recursos diferentes para atualizar / obter / excluir e Criar. Tal como

  • Criar - usando / recursos com o método POST (observe o plural) em alguns lugares usando / resource (singular)
  • Atualização - usando / resource / 123 com o método PUT
  • Obter - Usando / resource / 123 com o método GET

Estou um pouco confuso sobre esta convenção de nomes de URI. O que devemos usar no plural ou no singular para criação de recursos? Quais devem ser os critérios ao decidir isso?

JPReddy
fonte
9
Após este tópico, coletei alguns exemplos de APIs REST famosas em um artigo: inmensosofa.blogspot.com/2011/10/… .
jjmontes
3
A conclusão que cheguei depois de ler todas as respostas abaixo: Sempre use singular porque (a) é consistente, (b) mapeia diretamente para nomes de classes e tabelas singulares, (c) alguns substantivos plurais são irregulares (imprevisíveis) em inglês
Will Sheppard
Veja esta resposta para um link para convenções de nomenclatura de tabela singular, e não há outro um artigo que menciona esta questão exata Dilemma Resto API do desenvolvedor - obrigado @Sorter
Will Sheppard

Respostas:

281

A premissa de usar /resourcesé que ele representa "todos" os recursos. Se você fizer um GET /resources, provavelmente retornará a coleção inteira. Ao postar em /resources, você está adicionando à coleção.

No entanto, os recursos individuais estão disponíveis em / resource. Se você fizer um GET /resource, provavelmente cometerá um erro, pois essa solicitação não faz nenhum sentido, enquanto /resource/123faz todo o sentido.

Usando /resourcevez de /resourcesé semelhante à forma como você faria isso se estivesse a trabalhar com, digamos, um sistema de arquivos e uma coleção de arquivos e /resourceé o "diretório" com o indivíduo 123, 456arquivos nele.

De nenhuma maneira é certo ou errado, escolha o que você mais gosta.

Will Hartung
fonte
55
Ótima resposta! Mas os diretórios "padrão" no Windows têm nomes no plural . Como "Arquivos de programas", "Usuários", "Documentos", "Vídeos" etc. Também encontrei nomes plurais em URLs de sites com muito mais frequência.
Dmitry Gonchar 12/04
50
a convenção defacto que a maioria das pessoas e APIs adotam é mantê-la plural o tempo todo. Os IDs especificam UM recurso cars / id
PositiveGuy
205
"De nenhuma maneira é certo ou errado, escolha o que você mais gosta." Ah, a famosa frase que ouço com frequência e fico enjoada de ouvir as pessoas. As convenções são importantes e DEVEM ser debatidas construtivamente entre a comunidade, é aí que surgem melhores soluções e boas práticas. Quando você está usando plural e singular para nomes de recursos em URIs, isso complica seu código e a API, porque o usuário e o código por trás da API precisam levar isso em conta nas rotas e na lógica para diferenciar single vs. plural, enquanto se você apenas mantiver com plural o tempo todo, você não tem problemas.
PositiveGuy
30
@TomaszPluskiewicz Você tem toda a razão de que os clientes não se importam. Como desenvolvedores de software , devemos nos preocupar - e por isso concordo com o comentário da WTF de que debates construtivos sobre convenções são valiosos.
Travis D
12
Alguém pode simplesmente colocar uma resposta de uma palavra e aceitá-la, para que eu não precise ler tudo de novo (de novo).
Ben George
623

Para mim, é melhor ter um esquema que você possa mapear diretamente para o código (fácil de automatizar), principalmente porque o código é o que será nas duas extremidades.

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) 
jla
fonte
22
A dificuldade ou facilidade disso se deve a não respeitar o HATEOS. Não importa se é plural ou singular ou qualquer outra coisa. Você deve respeitar os URLs enviados pelo servidor e não "construir" seus URLs no cliente. Então você tem 0 mapeamento para fazer no seu código.
Richard
7
@richard O cliente ainda precisa fazer o mapeamento. No HATEOS, eles precisariam mapear para um nome que represente o relacionamento (rel) com a construção do URI. O rel, método (verbo) e Content-Type compõem a mídia de recurso. Isso não exclui a necessidade de um bom design de URI. Embora o cliente possa dar precedência ao nome do rel, os desenvolvedores da API ainda precisam de um bom padrão legível por humanos para a construção de URI.
4
Esta é uma resposta melhor na minha opinião. Exceto que eu sempre preferi usar o Singular em vez do plural. User.getList (), User.getById, User.delete etc.
Eastern Monk
3
Eu gosto da simplicidade. O mapeamento também tem o benefício de tornar a documentação e testes em rotas incrivelmente fáceis de escrever.
delos 31/03
5
Isso faz sentido para mim. No entanto, somos uma primeira loja de banco de dados, o que significa que geramos entidades de código e API do nosso esquema de banco de dados. E os padrões de banco de dados tendem a defender nomes de tabelas singulares, por isso vamos continuar com isso, mas ainda sob a mesma lógica que esta resposta.
André C. Andersen
274

Também não vejo sentido em fazer isso e acho que não é o melhor design de URI. Como usuário de um serviço RESTful, eu esperaria que o recurso da lista tivesse o mesmo nome, independentemente de acessar a lista ou o recurso específico 'na' lista. Você deve usar os mesmos identificadores, independentemente de querer usar o recurso de lista ou um recurso específico.

Jan Deinhard
fonte
69
Esta é a melhor resposta para mim. Aprecio que os designers da API gostem da correção linguística de dizer "obtenha o recurso # 123", mas é um trabalho extra de codificação ao escrever clientes da API, bem como documentação de ajuda. (GET / api / people vs. GET / api / person / 123? Euuuchh.) .... em vez de pensar nisso como "obter recurso # 123", coloque-o na sua cabeça como "obtenha da coleção de recursos que corresponde a # 123 ".
Warren Rumak
5
Distinguir recursos plurais / singulares não é sobre correção lingüística, mas sobre escala. / employee / 12 lê para mim como o subconjunto do recurso de funcionários com o ID '12' (isso pode significar qualquer coisa, por exemplo, uma consulta de pesquisa salva em funcionários demitidos recentemente). Se você leu acima como o funcionário com o ID '12', como você representaria o subconjunto? A única opção é tornar as coleções de minério mais complexas do URI, que distinguem objetos dos próprios objetos (por exemplo, singular versus plural).
Erik
9
Escolher / employee / 12 para representar uma consulta de pesquisa em funcionários demitidos recentemente (ou qualquer subconjunto) seria um design ruim, eu acho. Se você deseja representar subconjuntos de qualquer tipo, sugiro apresentá-los como recursos (com nomes próprios).
Jan Deinhard
3
Isso não tem nada a ver com a compreensão dos clientes. Trata-se de abordar coisas diferentes com URLs diferentes. E poder responder a todos os métodos HTTP sem estar em conflito. Você pode ter um recurso que é uma coleção de itens e um recurso que representa um item em si. Pelo que sei, o recurso de coleções pode ser example.org/166316e2-e1 e um item específico nessa coleção example.org/20d68348-ccc-001c4200de . O cliente não deve construir URLs (que obviamente não escalam, não são RESTful e é para isso que servem os tipos de relação de link).
Erik
4
Se você não acha que URLs arbitrários são bonitos, sinta-se à vontade para identificar um recurso de coleção com um nome plural e um item individual com um nome singular. Se você não gosta de URLs em inglês e seu idioma natural não suporta essa forma de notação singular / plural, use outra coisa para defini-lo no seu idioma preferido. Suponho que todos os idiomas permitam distinguir de alguma forma '/ a coleção de- bla / 2321 'versus' bla / 61 'por escrito. E cada um desses dois recursos diferentes representa resultados completamente diferentes ao enviar GET / PUT / DELETE / POST / PATCH e outros.
Erik
77

Plural

  • Simples - todos os URLs começam com o mesmo prefixo
  • Lógico - orders/obtém uma lista de pedidos de índice.
  • Padrão - O padrão mais amplamente adotado, seguido pela esmagadora maioria das APIs públicas e privadas.

Por exemplo:

GET /resources - retorna uma lista de itens de recursos

POST /resources - cria um ou muitos itens de recursos

PUT /resources - atualiza um ou muitos itens de recursos

PATCH /resources - atualiza parcialmente um ou muitos itens de recursos

DELETE /resources - exclui todos os itens de recursos

E para itens de recurso único:

GET /resources/:id- retorna um item de recurso específico com base no :idparâmetro

POST /resources/:id - cria um item de recurso com o ID especificado (requer validação)

PUT /resources/:id - atualiza um item de recurso específico

PATCH /resources/:id - atualiza parcialmente um item de recurso específico

DELETE /resources/:id - exclui um item de recurso específico

Para os defensores do singular, pense dessa maneira: você pediria a alguém ordere esperaria uma coisa ou uma lista de coisas? Então, por que você esperaria que um serviço retornasse uma lista de itens ao digitar /order?

Eric Knudtson
fonte
10
Singular : no caso, quando parte do seu sistema é apenas um objeto (0-1, existe ou não), por exemplo, users / 1 / avatar, você pode usar uma forma singular para rotular esse único objeto (por exemplo, avatar) - exemplo mais detalhado aqui: stackoverflow .com / a / 38296217/860099 . BTW - resposta muito bom :)
Kamil Kiełczewski
E o mapeamento para nomes de classes e tabelas, que devem ser singulares? (veja outra resposta )
Will Sheppard
@WillSheppard - Os nomes das classes são melhores na forma singular e os nomes das tabelas são melhores na forma plural. Por exemplo, Orderé um bom nome para uma classe que lida com instâncias singulares de objetos referentes a uma ordem. OrderListé um nome para uma classe que lida com várias Orderinstâncias. Orders Tableé um bom nome para uma tabela de banco de dados de muitos pedidos.
Eric Knudtson
Eu quero receber / encomendas, mas eu só quero / 1
jim smith
@ Jim-Smith, por que você não solicita / 1 da coleção de usuários com GET / users / 1?
Rohmer
49

Singular

Conveniência As coisas podem ter nomes irregulares no plural. Às vezes eles não têm um. Mas nomes singulares estão sempre lá.

por exemplo, CustomerAddress sobre CustomerAddresses

Considere este recurso relacionado.

Isso /order/12/orderdetail/12é mais legível e lógico do que /orders/12/orderdetails/4.

Tabelas de banco de dados

Um recurso representa uma entidade como uma tabela de banco de dados. Deve ter um nome singular lógico. Aqui está a resposta sobre os nomes das tabelas.

Mapeamento de Classes

As aulas são sempre singulares. As ferramentas ORM geram tabelas com os mesmos nomes dos nomes de classe. À medida que mais e mais ferramentas estão sendo usadas, nomes singulares estão se tornando um padrão.

Leia mais sobre o dilema de um desenvolvedor de API REST

Classificador
fonte
39
Nomes singulares estão sempre lá /clothe/12/trouser/34 :)
Gert Arnold
18
@GertArnold a palavra clotheé um verbo. As APIs de descanso geralmente se atêm aos substantivos ao falar sobre recursos e usam verbos ao descrever ações. A forma singular é clout, mas é arcaica e provavelmente seria mais adequadamente substituída por garment.
21817 Steve Buzonas
@SteveBuzonas E para calças e óculos de sol?
Koray Tugay
32

Enquanto a prática mais prevalente são as APIs RESTful onde plurais são usados /api/resources/123, por exemplo , há um caso especial em que considero o uso de um nome singular mais apropriado / expressivo do que nomes plurais. É o caso dos relacionamentos um-para-um. Especificamente, se o item de destino for um objeto de valor (no paradigma de design controlado por domínio).

Vamos supor que todo recurso tenha um um para um, accessLogque pode ser modelado como um objeto de valor, ou seja, não uma entidade, portanto, sem ID. Pode ser expresso como /api/resources/123/accessLog. Os verbos usuais (POST, PUT, DELETE, GET) expressariam adequadamente a intenção e também o fato de que o relacionamento é realmente um para um.

redzedi
fonte
4
Boa tentativa. Mas seria melhor como "accessLogEntries". :-)
Tom Russell
8
@TomRussell por quê? As implicações disso são importantes. Entendo por que você usaria o plural, mesmo quando estiver acessando um recurso por um identificador, mas para muitos-para-um ou um-para-um é bastante enganador. Considere uma API que gerencia membros da equipe de uma empresa com vários locais. Cada membro da equipe trabalha em um local. GET /users/123/locationdeve buscar o local em que o usuário trabalha. Não é GET /users/123/locationsrealmente enganoso como consumidor?
Carrie Kendall
1
@CarrieKendall Entendo o seu ponto. Como accessLogé modelado como um atributo ou valor, em vez de uma entidade, deve ser singular. Se você tiver excesso de engenharia, uma entrada de log seria uma entidade e você o faria /api/accessLogEntries?resource=123.
Tom Russell
Concordo, no entanto, acho que quebra a convenção de pluralizar todas as coisas. É complicado. Para mim, é importante que uma API seja direta, ou seja, a documentação deve complementar uma implementação já direta.
Carrie Kendall
Sou mais programador do que pessoa de sistemas ou banco de dados, por isso gosto de uma API que conta uma história, em vez de aderir à convenção. As implicações para a documentação automatizada são reais, no entanto.
Tom Russell
26

Por que não seguir a tendência predominante dos nomes de tabelas de banco de dados, onde geralmente é aceito um formulário singular? Estive lá, fiz isso - vamos reutilizar.

Dilema de nomeação de tabela: nomes singulares vs. plurais

Slawomir
fonte
8
Das Auto é muito melhor que Die Autos. Além disso, as convenções do plural do inglês não são consistentes.
FlavourScape
7
O espaço para nome do recurso é uma questão de semântica, não de implementação. Portanto, usar a analogia das tabelas do banco de dados não é muito afortunado. Além disso, ao trabalhar com DB-s, você está manipulando apenas tabelas, mas é claro que pode afetar o conteúdo (linhas), mas no REST não há restrição para manipular diretamente um único recurso.
Arpadf
3
Eu acho que essa é uma boa analogia, mas mais importante do que decidir se é singular ou plural é ser consistente com o que você escolher. Você não vai inserir em Usuários e depois selecionar Usuário. A mesma regra deve se aplicar aos recursos REST - não os renomeie, dependendo do que você está fazendo.
Todd Menier
3
Não são apenas nomes de tabelas, também são comparáveis ​​aos nomes de classes em OO (minha classe seria chamada de Cliente, não Clientes).
Bydevev
Neste caso, semântica é muito importante para simplesmente aceitar as tendências "já definidos"
Cattani Simone
19

Estou surpreso ao ver que tantas pessoas pulariam no substantivo plural bandwagon. Ao implementar conversões no singular para o plural, você cuida de substantivos no plural irregulares? Você gosta de dor?

Consulte http://web2.uvcs.uvic.ca/elc/studyzone/330/grammar/irrplu.htm

Existem muitos tipos de plural irregular, mas estes são os mais comuns:

Tipo substantivo Formando o plural Exemplo

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)
Stephan Erickson
fonte
5
Eu não entendo a preocupação aqui. Não devemos mudar o singular para o plural por meio de programação. A maioria das formas plurais acima são bem conhecidas e não devem ser uma preocupação. Se alguém tiver pouco conhecimento de inglês, ele escreverá incorretamente qualquer parte da sua variável. Além disso, seguindo sua lógica, você também recomenda o uso de formulários singulares para referenciar coleções no código-fonte também?
Kishor borate 18/04/19
1
Existem palavras em inglês que são irregulares a ponto de muitas vezes ser um problema, mesmo na Anglosfera, e são termos comumente usados ​​como índice / índices / índices, vertigem / vertigem / vértices, matriz / matrizes / matrizes, raio / raios / raios, etc. Não vejo sentido em tornar os caminhos REST plurais de qualquer maneira, porque se todos são consistentemente singulares, é apenas mais óbvio para todos.
DAMD
@kishorborate, Usar o plural como URI é mais suscetível a erros, mesmo para falantes nativos de inglês. Como damd indica, plurais como índice / índices / índices estão introduzindo mais problemas. E existem substantivos incontáveis. Misturar substantivos incontáveis ​​com plurais é outro problema. Por que tornar mais difícil para os programadores gastar mais tempo com isso? Sugiro usar singulares para tudo. Se houver um / {id}, a API deverá retornar um único registro. Se não houver um / {id} a seguir, a API deverá retornar a coleção.
Daming Fu
3
O recurso Singular do @DamingFu nem sempre pode ter um ID associado a ele. por exemplo. / user / {id} / nickName Ao olhar para ele, não está claro se ele retornará uma lista de apelidos ou apelido único? Portanto, as APIs são mais intuitivas quando usam formas plurais. Sim, poucas palavras terão formas irregulares no plural. Para alguém que está lendo a forma plural, não é um problema. É problema apenas ao escrever a assinatura da API. Mas a frequência de tais palavras não é alta, também, encontrar a forma plural de qualquer palavra não é demorado. É uma troca que devemos aceitar, para tornar as APIs mais intuitivas.
Kishor borate 06/12/19
15

Da perspectiva do consumidor da API, os pontos de extremidade devem ser previsíveis para que

Idealmente...

  1. GET /resources deve retornar uma lista de recursos.
  2. GET /resource deve retornar um código de status de 400 níveis.
  3. GET /resources/id/{resourceId} deve retornar uma coleção com um recurso.
  4. GET /resource/id/{resourceId} deve retornar um objeto de recurso.
  5. POST /resources o lote deve criar recursos.
  6. POST /resource deve criar um recurso.
  7. PUT /resource deve atualizar um objeto de recurso.
  8. PATCH /resource deve atualizar um recurso postando apenas os atributos alterados.
  9. PATCH /resources Os recursos de atualização em lote devem postar apenas os atributos alterados.
  10. DELETE /resourcesdeve excluir todos os recursos; brincando: código de status 400
  11. DELETE /resource/id/{resourceId}

Essa abordagem é a mais flexível e rica em recursos, mas também a que consome mais tempo. Portanto, se você estiver com pressa (o que é sempre o caso do desenvolvimento de software), apenas nomeie seu endpoint resourceou a forma plural resources. Eu prefiro a forma singular, pois oferece a opção de examinar e avaliar programaticamente, pois nem todas as formas plurais terminam em 's'.

Dito tudo isso, por qualquer motivo que o desenvolvedor da prática mais comumente escolhido tenha escolhido é usar a forma plural. Esta é finalmente a rota que eu escolhi e se você olhar as APIs populares como githubetwitter , é isso que elas fazem.

Alguns critérios para decidir podem ser:

  1. Quais são as minhas restrições de tempo?
  2. Quais operações permitirei que meus consumidores façam?
  3. Como é a carga útil da solicitação e do resultado?
  4. Quero poder usar a reflexão e analisar o URI no meu código?

Então a escolha é sua. Seja o que for que seja consistente.

cosbor11
fonte
1
Parece que a forma plural foi escolhida porque os desenvolvedores parecem assumir que todos os recursos fazem parte de alguma coleção. No entanto, a "convenção aceita" parece indicar que POST /usersdeve criar um único usuário, adicionando-o à coleção. Discordo. POST /usersdeve criar uma lista de usuários (mesmo que seja uma lista de 1), onde também POST /userdeve criar exatamente um usuário. Não vejo razão para que os pontos de extremidade do recurso plural e singular não possam coexistir. Eles descrevem comportamentos diferentes e não devem surpreender ninguém de sua função.
esmagar
Não existe uma convenção para especificar uma identificação de recurso no caminho? Nesse caso, parece ser amplamente negligenciado. Por exemplo, POST users/<id>criaria um novo usuário.
Tom Russell
1
@ TomRussell geralmente o servidor cria o ID, então você ainda não saberia o ID para POST.
1628 Alex
3
@ TomRussell, quando o cliente determina (um tipo de) identificação ao criar um novo recurso, é mais comum usar em PUT /users/<id>vez de POST. POSTtem a interpretação "adicione isso à coleção e determine o ID como parte disso". PUTtem a interpretação "atualizar (ou adicionar) esse recurso com esse ID". Consulte restcookbook.com/HTTP%20Methods/put-vs-post para obter uma explicação mais detalhada desse princípio.
Jochem Schulenklopper 13/09
Não acredito que a comparação com a API do Twitters seja justa, pois eles usam o formulário Plural para todos os seus endpoints. Eles não misturam Plural e Singular para os mesmos elementos.
Andrew T Finnell 19/07/19
7

Meus dois centavos: métodos que passam seu tempo mudando do plural para o singular ou vice-versa são um desperdício de ciclos de CPU. Eu posso ser da velha escola, mas na minha época as coisas eram chamadas da mesma forma. Como procuro métodos relacionados a pessoas? Nenhuma expressão regular cobre pessoas e pessoas sem efeitos colaterais indesejáveis.

Os plurais em inglês podem ser muito arbitrários e sobrecarregam o código desnecessariamente. Atenha-se a uma convenção de nomenclatura. As linguagens de computador deveriam ter clareza matemática, não imitar a linguagem natural.

Guichito
fonte
2
Isso aborda o código que tenta "gerar automaticamente / manipular pontos de extremidade" (existem muitas bibliotecas opinativas que assumem pluralidade / singularidade e tentam mapear); no entanto, isso se aplica a nomes de pontos de extremidade escolhidos explicitamente, mais do que escolher a palavra certa (independentemente de como ela é pluralizada).
user2864740
6

Eu prefiro usar a forma singular para simplicidade e consistência.

Por exemplo, considerando o seguinte URL:

/ cliente / 1

Tratarei o cliente como uma coleção de clientes, mas por simplicidade, a parte da coleção é removida.

Outro exemplo:

/ equipamento / 1

Nesse caso, equipamentos não é a forma plural correta. Portanto, tratá-lo como uma coleção de equipamentos e remover a coleção por simplicidade torna-o consistente com o caso do cliente.

ivxivx
fonte
2
O POST / cliente parece substituir o único cliente. Essa é minha maior tristeza com o uso de nomes de recursos singulares.
Andrew T Finnell
2
@ andrew-t-finnell Não POST /customerdeveria fazer exatamente isso - inserir um único cliente?
donmutti
Ele insere um único cliente em uma coleção de clientes. POST /customerlê para mim como se estivesse postando para o thecliente. Não é uma coleção de clientes. No entanto, admito que Plural ou não Plural é uma preferência. Contanto que eles não sejam misturados como a outra Resposta. Isso seria incrivelmente confuso.
Andrew T Finnell 19/07/19
"POSTAR PARA O CLIENTE" não faz sentido neste caso. O POST não substitui, ele insere. Talvez se fosse POST / customer / 1 eu pudesse ver o dilema, mas mesmo isso não faz muito sentido da perspectiva REST, porque o que você está inserindo? Seria / cliente / 1 / factura ou / cliente / 1 / recibo, etc.
DAMD
5

Um ID em uma rota deve ser exibido da mesma forma que um índice para uma lista e a nomeação deve prosseguir de acordo.

numbers = [1, 2, 3]

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

Mas alguns recursos não usam IDs em suas rotas porque há apenas um ou um usuário nunca tem acesso a mais de um, portanto, essas não são listas:

GET /dashboard
DELETE /session
POST /login
GET /users/{:id}/profile
UPDATE /users/{:id}/profile
TiggerToo
fonte
4

Nas convenções de nomenclatura, geralmente é seguro dizer "apenas escolha uma e cumpra-a", o que faz sentido.

No entanto, depois de ter que explicar o REST para muitas pessoas, representar os pontos de extremidade como caminhos em um sistema de arquivos é a maneira mais expressiva de fazê-lo.
É sem estado (os arquivos existem ou não existem), hierárquico, simples e familiar - você já sabe como acessar arquivos estáticos, localmente ou via http.

E, nesse contexto, as regras lingüísticas podem levá-lo até o seguinte:

Um diretório pode conter vários arquivos e / ou subdiretórios e, portanto, seu nome deve estar na forma plural.

E eu gosto disso.
Embora, por outro lado - seja seu diretório, você pode chamá-lo de "um recurso ou vários recursos", se é isso que você deseja. Isso não é realmente o importante.

O importante é que, se você colocar um arquivo chamado "123" em um diretório chamado "resourceS" (resultando em /resourceS/123), não poderá esperar que ele seja acessível via/resource/123 .

Não tente torná-lo mais inteligente do que deveria ser - mudar de plural para singluar, dependendo da quantidade de recursos que você está acessando no momento, pode ser esteticamente agradável para alguns, mas não é eficaz e não faz sentido em um hierárquico sistema .

Nota: Tecnicamente, você pode criar "links simbólicos", para que /resources/123também possam ser acessados ​​via /resource/123, mas o primeiro ainda precisa existir!

Narf
fonte
3

Dê uma olhada no Google 's Guia de Design do API: Nomes de Recursos para outra tomada sobre os recursos de nomeação.

Em resumo:

  • As coleções são nomeadas com plurais.
  • Recursos individuais são nomeados com uma sequência.
|--------------------------+---------------+-------------------+---------------+--------------|
| 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   |
|--------------------------+---------------+-------------------+---------------+--------------|

Vale a pena ler se você está pensando sobre esse assunto.

Shannon Matthews
fonte
2

Usar o plural para todos os métodos é mais prático, pelo menos em um aspecto: se você estiver desenvolvendo e testando uma API de recurso usando o Postman (ou ferramenta similar), não precisará editar o URI ao alternar de GET para PUT para POST etc. .

Paulo Merson
fonte
1
Não é um argumento para mim, pois o Postman oferece coleções, para que você possa salvar todos os recursos como itens de coleção diferentes e testá-los individualmente. Tudo o que você faz é selecionar recursos da coleção, não precisa editar parâmetros / métodos / etc sempre.
Wirone
1

Ambas as representações são úteis. Eu tinha usado o singular por conveniência há algum tempo, a inflexão pode ser difícil. Minha experiência no desenvolvimento de APIs REST estritamente singulares, os desenvolvedores que consomem o endpoint não têm certeza de qual seja a forma do resultado. Agora, prefiro usar o termo que melhor descreve a forma da resposta.

Se todos os seus recursos forem de nível superior, você poderá obter representações singulares. Evitar a inflexão é uma grande vitória.

Se você está fazendo algum tipo de link direto para representar consultas sobre relações, os desenvolvedores que escrevem na sua API podem ser auxiliados por uma convenção mais rígida.

Minha convenção é que cada nível de profundidade em um URI está descrevendo uma interação com o recurso pai, e o URI completo deve descrever implicitamente o que está sendo recuperado.

Suponha que tenhamos o seguinte modelo.

interface User {
    <string>id;
    <Friend[]>friends;
    <Manager>user;
}

interface Friend {
    <string>id;
    <User>user;
    ...<<friendship specific props>>
}

Se eu precisasse fornecer um recurso que permita que um cliente obtenha o gerente de um amigo em particular de um usuário em particular, pode parecer algo como:

GET /users/{id}/friends/{friendId}/manager

A seguir, apresentamos mais alguns exemplos:

  • GET /users - liste os recursos do usuário na coleção de usuários globais
  • POST /users - crie um novo usuário na coleção de usuários globais
  • GET /users/{id} - recuperar um usuário específico da coleção de usuários globais
  • GET /users/{id}/manager - obtenha o gerente de um usuário específico
  • GET /users/{id}/friends - obtenha a lista de amigos de um usuário
  • GET /users/{id}/friends/{friendId} - obtenha um amigo específico de um usuário
  • LINK /users/{id}/friends - adicione uma associação de amigos a este usuário
  • UNLINK /users/{id}/friends - remover uma associação de amigos deste usuário

Observe como cada nível é mapeado para um pai que pode agir. Usar pais diferentes para o mesmo objeto é contra-intuitivo. A recuperação de um recurso em GET /resource/123não deixa indicação de que a criação de um novo recurso deve ser feita emPOST /resources

Steve Buzonas
fonte
1

Eu sei que a maioria das pessoas está entre decidir entre usar o plural ou o singular. O problema que não foi abordado aqui é que o cliente precisará saber qual você está usando e é sempre provável que cometa um erro. É daí que vem minha sugestão.

E os dois? E com isso, quero dizer usar singular para toda a API e criar rotas para encaminhar solicitações feitas no plural para o singular. Por exemplo:

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

Você entendeu a foto. Ninguém está errado, com um esforço mínimo, e o cliente sempre acertará.

wynnset
fonte
1
Se você estiver fazendo redirecionamentos 302 e seu cache estiver armazenando tudo duas vezes, você configurou seu cache incorretamente. O cache não deve armazenar 302 redirecionamentos.
Wynnset
2
Se o seu cliente sempre usa /resourcese sempre é redirecionado /resource, você fez errado. Se outra pessoa usa sua API, ela pode usar o URL correto diretamente ou ser redirecionada (o que funciona, mas está errado) e foi você quem abriu o caminho errado.
Maaartinus
Não sei ao certo o que você quer dizer com "errado" - isso é muito subjetivo. Não está realmente errado, porque funciona.
Wynnset 17/05
Isso aumenta o custo de manutenção, o custo de entendimento e a quantidade de código necessária.
Will Sheppard
1

Não gosto de ver a {id}parte dos URLs se sobrepor aos sub-recursos, pois, idteoricamente, isso poderia ser qualquer coisa e haveria ambiguidade. Está misturando diferentes conceitos (identificadores e nomes de sub-recursos).

Problemas semelhantes são freqüentemente vistas em enumconstantes ou pasta estruturas, onde diferentes conceitos são misturados (por exemplo, quando você tem pastas Tigers, Lionse Cheetahs, em seguida, também uma pasta chamada Animalsno mesmo nível - isso não faz sentido como um é um subconjunto do de outros).

Em geral, acho que a última parte nomeada de um endpoint deve ser singular se lida com uma única entidade de cada vez e plural se lida com uma lista de entidades.

Portanto, terminais que lidam com um único usuário:

GET  /user             -> Not allowed, 400
GET  /user/{id}        -> Returns user with given id
POST /user             -> Creates a new user
PUT  /user/{id}        -> Updates user with given id
DELETE /user/{id}      -> Deletes user with given id

Depois, há um recurso separado para fazer consultas aos usuários, que geralmente retornam uma lista:

GET /users             -> Lists all users, optionally filtered by way of parameters
GET /users/new?since=x -> Gets all users that are new since a specific time
GET /users/top?max=x   -> Gets top X active users

E aqui estão alguns exemplos de um sub-recurso que lida com um usuário específico:

GET /user/{id}/friends -> Returns a list of friends of given user

Faça um amigo (link muitos para muitos):

PUT /user/{id}/friend/{id}     -> Befriends two users
DELETE /user/{id}/friend/{id}  -> Unfriends two users
GET /user/{id}/friend/{id}     -> Gets status of friendship between two users

Nunca há ambiguidade, e a nomeação plural ou singular do recurso é uma dica para o usuário o que ele pode esperar (lista ou objeto). Não há restrições sobre ids, teoricamente tornando possível ter um usuário com o ID newsem sobrepor-se a um nome de sub-recurso (potencial futuro).

john16384
fonte
1

Use o Singular e aproveite a convenção em inglês vista em, por exemplo, "Business Directory".

Muitas coisas são lidas desta maneira: "estante de livros", "matilha de cães", "galeria de arte", "festival de cinema", "estacionamento de carros" etc.

Isso corresponde convenientemente ao caminho da URL da esquerda para a direita. Tipo de item à esquerda. Defina o tipo à direita.

Será que GET /usersrealmente sempre buscar um conjunto de usuários? Normalmente não. Ele busca um conjunto de stubs contendo uma chave e talvez um nome de usuário. Portanto, não é realmente /usersassim mesmo. É um índice de usuários, ou um "índice de usuário", se você preferir. Por que não chamar assim? É um /user/index. Como nomeamos o tipo de conjunto, podemos ter vários tipos mostrando diferentes projeções de um usuário sem recorrer a parâmetros de consulta, por exemplo, user/phone-listou /user/mailing-list.

E o Usuário 300? Ainda está /user/300.

GET /user/index
GET /user/{id}

POST /user
PUT /user/{id}

DELETE /user/{id}

No fechamento, o HTTP pode ter apenas uma única resposta para uma única solicitação. Um caminho está sempre se referindo a algo singular.

Samuel Danielson
fonte
-1

Para mim, os plurais manipulam a coleção , enquanto os singulares manipulam o item dentro dessa coleção.

A coleção permite os métodos GET / POST / DELETE

O item permite os métodos GET / PUT / DELETE

Por exemplo

O POST em / alunos adicionará um novo aluno à escola.

DELETE ativado / alunos removerá todos os alunos da escola.

DELETE em / student / 123 removerá o aluno 123 da escola.

Pode parecer sem importância, mas alguns engenheiros às vezes esquecem o id. Se a rota sempre foi plural e executou um DELETE, você pode acidentalmente limpar seus dados. Enquanto a falta do ID no singular retornará uma rota 404 não encontrada.

Para expandir ainda mais o exemplo, se a API deveria expor várias escolas, algo como

DELETE em / school / abc / students removerá todos os alunos da escola abc.

Escolher a palavra certa às vezes é um desafio por si só, mas eu gosto de manter a pluralidade da coleção. Por exemplo, cart_itemsou cart/itemsparece certo. Ao contrário cart, a exclusão exclui o objeto do carrinho e não os itens do carrinho;).

ruralcoder
fonte
Isso não deve ser dividido é / cart e / cart / item (s) de qualquer maneira? Então você pode abordar o carrinho inteiro (por exemplo, com uma exclusão) ou itens individuais?
Rob Grant
@RobertGrant Isso não seria "/ carrinhos / itens / 123"? (por exemplo, por que "carrinho" e não "carrinhos" é a regra 'sempre plural'?)
user2864740
1
Eu diria que, se o código de produção estiver registrado e puder executar uma exclusão dos itens do carrinho de todos, haverá problemas maiores do que a convenção de nomenclatura. A probabilidade de eles se lembrarem de um ID é muito menor.
Andrew T Finnell
alguém criaria um ponto final que simplesmente exclui uma coleção inteira? Parece extremamente perigoso para mim, e provavelmente também porque o REST realmente não suporta exclusões em lote. (você teria que agrupar a matriz em um objeto). Se eu precisasse absolutamente de um nó de extremidade para excluir uma coleção inteira, garantiria que o URI fosse muito único e definitivamente não seja semelhante ao POST
cnps
-1

E se:

/resource/ (não /resource )

/resource/ significa que uma pasta contém algo chamado "recurso", é uma pasta "recurso".

E também acho que a convenção de nomenclatura das tabelas de banco de dados é a mesma, por exemplo, uma tabela chamada 'user' é uma "tabela de usuário", contém algo chamado "usuário".

chrisyue
fonte
-2

Prefiro usar o plural ( /resources) e o singular ( /resource/{id}) porque acho que separa mais claramente a lógica entre trabalhar na coleção de recursos e trabalhar em um único recurso.

Como um efeito colateral importante disso, também pode ajudar a impedir que alguém use a API incorretamente. Por exemplo, considere o caso em que um usuário tenta obter um recurso incorretamente, especificando o ID como um parâmetro como este:

GET /resources?Id=123

Nesse caso, onde usamos a versão plural, o servidor provavelmente ignorará o parâmetro Id e retornará a lista de todos os recursos. Se o usuário não for cuidadoso, ele pensará que a chamada foi bem-sucedida e usará o primeiro recurso da lista.

Por outro lado, ao usar a forma singular:

GET /resource?Id=123

o servidor provavelmente retornará um erro porque o ID não está especificado da maneira correta e o usuário terá que perceber que algo está errado.

pberggreen
fonte
1
Por que você está misturando idiomas aqui? Você usa a notação de URI adequada no primeiro parágrafo e muda para os parâmetros de consulta? O uso de parâmetros de consulta para obter um recurso com um ID 123 é totalmente errado aqui.
Andrew T Finnell
Isso foi claramente um erro. Atualizei minha resposta agora. Obrigado por perceber.
Pberggreen #
Depois de ter sido votado novamente novamente, examinei o que escrevi e percebi que a postagem original estava correta. Meu argumento era exatamente que, se o usuário fizer a coisa errada, usar plural + singular fornecerá uma mensagem de erro melhor do que usar apenas plural.
Pberggreen # 23/18
Ainda sinto que isso está confundindo o problema em questão. A idéia de usar o plural é que é uma coleção. E o número no final é um índice para a coleção. E se você GET / recurso por si só? Usar o plural e o singular juntos é bastante confuso. Dizendo / resources / 123 diz: Coloque meu recurso 123 no balde de recursos.
Andrew T Finnell