Como criar pontos de extremidade da API para postar um objeto filho e obter todos os filhos de todos os pais?

12

Por exemplo, tenho entidades: Cliente, Relatório. O cliente pode ter muitos relatórios e acho que o ponto final de um único gerenciamento de relatórios deve ser aninhado assim:

/clients/{client_id}/reports/{report_id}

Quanto a todos os relatórios de um cliente, o enpoint é esperado:

/clients/{client_id}/reports

Mas como deve ser um ponto de extremidade para obter todos os relatórios de todos os clientes para manter a API consistente e bem projetada.

Minhas abordagens:

  1. (Eu vi em algumas APIs do Google) use "-" em vez dele e analise-o como "todos":

/clients/-/reports

Isso mantém o formato do ponto final o mesmo, mas parece um pouco incomum, não consegue encontrar nenhum rfc que sugira esse caminho.

  1. Faça um ponto de extremidade separado apenas para todos os relatórios:

/reports

Mas, para obter os relatórios do cliente, ainda é:

/clients/{client_id}/reports

  1. Refatorar pontos de extremidade para tornar o "cliente" não um pai, mas apenas um parâmetro de filtro:

/reports?client={client_id} - relatórios de um cliente

/reports - relatórios de todo o cliente

No caso de adicionar um novo terminal para postar um relatório para um cliente específico, pode parecer feio, porque será uma solicitação POST com um parâmetro na URL.

Existem outras sugestões de idéias?

Yann
fonte
2
Você pode estar interessado (a) em questão
Laiv

Respostas:

3

Mas como deve ser um ponto de extremidade para obter todos os relatórios de todos os clientes para manter a API consistente e bem projetada.

Antes de mais nada, lembre-se de que não há regras de ouro para modelar APIs RESTful. Tudo o que temos são boas práticas e convenções. Dito isto, a resposta provável é, como sempre, escolher a que melhor atende aos seus requisitos e, nesse caso, a que melhor expressa seu modelo.

Portanto, verifique as três opções da expressividade.

# 1 A notação "-"

Esta é uma ideia brilhante. Permite-nos expressar a condição a reportsque tudo pertenceclients . Está restringindo a "consulta" a um conjunto específico de relatórios (aqueles localizados dentro dos clientslimites).

Mantém a noção de hierarquia (pertencente) o tempo todo; portanto, se reportspuder ser encontrada em locais diferentes, essa notação é importante. Por exemplo:

  • Todos os relatórios que pertencem aos clientes /clients/-/reports
  • Todos os relatórios que pertencem aos departamentos /departments/-/reports
  • Todos os relatórios que pertencem aos funcionários /employees/-/reports

No entanto, para recuperar todos os relatórios disponíveis no sistema, manter a hierarquia não fornece nenhuma vantagem valiosa sobre a próxima opção.

# 2 URIs diferentes

Se não precisarmos expressar limites / contextos / hierarquia no momento de recuperar todos os relatórios disponíveis , essa abordagem me parecerá mais razoável.

O novo URI ( /reports) também deixa em aberto a possibilidade de um gerenciamento de relatórios . No entanto, não precisamos fornecer um suporte RESTful completo, se não considerarmos necessário. Por exemplo, você declarou Make a separate endpoint just for all the reports. Tudo bem, você só precisa implementar GETe talvez alguns filtros para consulta e é isso.

Observe que você ainda pode fazer isso /reports?client={client_id}. Ter um URI diferente para o mesmo recurso é bom. Alguns artigos que li chamariam isso de robustez .

# 3 Revertendo a hierarquia

Tenho a sensação de que essa abordagem não atende às suas expectativas. Além disso, acho que isso o levará ao ponto de partida.

Conclusões

Observe que os nºs 1 e 2 não são mutuamente exclusivos. Nós podemos implementar ambos. Dada a situação real e de acordo com as premissas do OP, eu implementaria apenas o número 2.


1: é equivalente a /clients/-/reportseu acho

Laiv
fonte
0

Os padrões de design da API do Google sugerem o uso de '-' nesse cenário.

GET /clients/-/reports

Fonte:

https://cloud.google.com/apis/design/design_patterns#list_sub-collections

wfg4
fonte
2
Longe de mim a discordar com o todo-poderoso Google, mas eu acho que eu prefiro algo como /client/{client_id}/report/{report_id}e/clients/report/{report_id}
Robert Harvey
2
@RobertHarvey porque não apenas /reports?
LAIV
@ Laiv: Isso implicaria todos os relatórios. Atualize sua página; Eu fiz uma edição ninja.
Robert Harvey
@RobertHarvey Quero dizer, por que não 2 pontos de extremidade diferentes /clients...e /reports.
LAIV
1
@Laiv: OK, mas isso apenas levanta a questão "Quais parâmetros devo colocar no corpo da solicitação?"
Robert Harvey