Estou no processo de criação de uma API REST e, atualmente, estou encontrando o seguinte problema:
Foo
é o primeiro recurso. As operações CRUD podem ser aplicadas via/foo/
URI.Bar
é o segundo recurso. As operações CRUD podem ser aplicadas via/bar/
URI.- Todos
Foo
estão associados a zero ou umBar
. A razão pela qual eu não tratoBar
como um sub-recurso deFoo
é porque a mesmaBar
instância pode ser compartilhada entre váriosFoo
. Por isso, achei melhor acessá-lo por meio de um URI independente em vez de/foo/[id]/bar
.
Meu problema é que, em uma quantidade significativa de casos, os clientes que solicitam uma Foo
instância também estão interessados na Bar
instância associada . Atualmente, isso significa que eles precisam executar duas consultas em vez de uma. Quero apresentar uma maneira que permita obter os dois objetos com uma única consulta, mas não sei como modelar a API para fazer isso. O que eu vim até agora:
- Eu poderia introduzir um parâmetro de consulta semelhante a este:
/foo/[id]?include_bar=true
. O problema dessa abordagem é que a representação do recurso (por exemplo, a estrutura JSON) da resposta precisaria parecer diferente (por exemplo, um contêiner, como em{ foo: ..., bar: ... }
vez de apenas um serializadoFoo
), o que torna oFoo
ponto final do recurso "heterogêneo". Eu não acho isso bom. Ao consultar/foo
, os clientes sempre devem obter a mesma representação de recurso (estrutura), independentemente dos parâmetros de consulta. - Outra idéia é introduzir um novo ponto de extremidade somente leitura, por exemplo
/fooandbar/[foo-id]
. Nesse caso, não há problema em retornar uma representação como{ foo: ..., bar: ... }
, porque é apenas a representação "oficial" dofooandbar
recurso. No entanto, não sei se esse ponto de extremidade auxiliar é realmente RESTful (foi por isso que escrevi "can" no título da pergunta. É claro que é tecnicamente possível, mas não sei se é uma boa idéia).
O que você acha? há outras possibilidades?
Bar
não pode existir sem estar associado a aFoo
. No entanto, como escrevi acima, é possível que váriosFoo
s compartilhem o mesmoBar
. Deveria ser possível criar umFoo
sem umBar
associado, por isso acho que nãoBar
deveria ser tratado como pai.Respostas:
Uma API REST de nível 3 retornará um
Foo
e também um link indicando o relacionadoBar
.Você pode adicionar um recurso "drill down" à sua API que permite a navegação de links;
O recurso de pesquisa detalhada fica na frente das APIs e intercepta as respostas. Ele faria as chamadas de busca detalhada e preenchia os detalhes antes de devolver a resposta ao chamador.
Isso é bastante comum no REST de nível 3, pois reduz bastante a conversação de cliente / servidor em http lento. A empresa em que trabalho produz uma API REST de nível 3 com exatamente esse recurso.
Atualização: quanto vale a pena, veja como ele pode parecer no JSON. É assim que nossa API a estruturaria. Observe que você pode aninhar suas pesquisas detalhadas para obter links de links etc.
fonte
links
matriz, cada entrada é um objeto de link comrel
umuri
campo e um (semelhante ao seu exemplo de xml). Devo apenas adicionar um terceiro campo a cada objeto de link (por exemplodata
)? Existe algum padrão?Se 95% de todas as consultas deseja
Foo
, bem comoBar
, em seguida, simplesmente devolvê-lo dentro doFoo
objeto quando você solicitar umFoo
. Basta adicionar uma propriedadebar
(ou algum outro termo para o relacionamento) e colocar oBar
objeto lá. Se o relacionamento não existir, use null.Eu acho que você está pensando demais nisso :)
fonte
Foo
e, uma vez que cada uma delasBar
é bastante grande na memória (cerca de 3x-4x o tamanhoFoo
), não quero retornar aBar
se um cliente não solicitar explicitamente.