Qual é a melhor estrutura de URL RESTful para um recurso recursivo?


10

Estou criando um serviço RESTfull para uma estrutura de recursos em forma de árvore e queria saber qual seria a melhor estrutura de URL?

Eu tenho três requisitos:

  1. ser capaz de obter uma coleção de recursos raiz
  2. ser capaz de obter um recurso individual
  3. ser capaz de obter uma coleção de recursos filho

Meu pensamento atual é:

/rest/documents
/rest/documents/{id}
/rest/documents/{id}/documents

Eu também estava pensando em seguir as rotas do singular / plural para denotar listas ou elementos individuais, mas sei que vou ter um recurso que é o mesmo plural que o singular, então decidi contra isso.

Alguém tem alguma opinião sobre o exposto? ou tem uma maneira diferente / melhor de estruturar isso?


Posso estar entendendo mal a pergunta, mas, como estamos falando de URLs, o SEO é um problema?
Jon Hopkins

SEO não é um problema, não. Estou basicamente pedindo a melhor estrutura lógica de URL para um recurso de auto-referência.
Matt Brailsford

Isso parece bastante direto para mim.
Tim Post

Qual a profundidade dessa estrutura?
Martijn Verburg

@Martijn a profundidade é ilimitada #
Matt Brailsford

Respostas:


11

O que me vem à mente é: não permita que a API RESTful reflita a recursividade no próprio URL. Venha para pensar sobre isso, seu recurso é apenas os documentos.

Se você tiver seus documentos armazenados fisicamente de acordo com a estrutura recursiva, crie um mapeamento para um ID exclusivo e use o ID no URL:

/rest/documents/{id}

Agora, se você possui seus documentos como este:

| DocumentName | DocumentPath | DocumentID |
--------------------------------------------
| abc | / abc | 1 |
| asd | / abc / asd | 2
| asd | / asd | 3
| vaia | / abc / asd / boo | 4
| ei / abc / asd / ei | 5

a solicitação consultaria esse URL para obter o /abc/asddocumento

GET /rest/documents/2

Portanto, agora você precisa fornecer aos usuários da sua API meios para percorrer sua estrutura com pouco esforço. Isso pode ser feito envolvendo sua carga útil de resposta (documento) em um objeto, contendo informações adicionais de travessia, como esta:

{
   data: { /* your document goes here */ },
   parent: {"abc": 1 },
   children: [ { "boo": 4 }, { "hey": 5} ]
}

desde que você espere que os usuários não criem muitos documentos em um único nível, inclua uma lista de filhos na resposta. Se não for esse o caso, você poderá oferecer ao usuário a recuperação de IDs de documentos filhos, permitindo, por exemplo, a paginação dos resultados por meio de parâmetros da string de consulta:

GET /rest/documents/2/children?page=2&size=50

Por fim, falando dos parâmetros da string de consulta, você também pode fornecer as informações do caminho diretamente através dos parâmetros da string de consulta:

GET /rest/documents?path=somepath&page=1&size=42

Todas as abordagens mencionadas esperam que a planície GET /rest/documentsretorne apenas documentos raiz.


11
Boa ideia. No entanto, o relacionamento com os documentos filho não é claro na API se os documentos filhos forem incluídos na resposta de um documento. Se os documentos também tiverem outro sub-recurso, por exemplo, comentários, você normalmente acessaria as perguntas de um documento usando / documents / {id} / questions. Para ser consistente e deixar claro o relacionamento com os documentos filhos na API, sugiro que os documentos filhos sejam acessados ​​por / documents / {id} / child-documents. As representações retornadas seriam documentos como / documents / {id}. Portanto, o restante do que você descreveu aqui ainda funciona também.
Nathan Ward

2

Algo assim talvez:

/rest/{rootEntity}/Item/{leafEntity}/{id}
/rest/{entity}/ItemList
/rest/{entity}/ItemList/{leafEntity}

onde {rootEntity} é o ponto de partida da sua coleção, {leafEntity} é qualquer nó da folha nomeado dentro da sua árvore.

Você pode acrescentar alguns parâmetros a qualquer um dos itens acima para selecionar, por exemplo, Mais recentes ou Todos ou algo assim.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.