¿Cómo diseñar puntos finales API para publicar un objeto hijo y para obtener todos los hijos de todos los padres?

12

Por ejemplo, tengo entidades: Cliente, Informe. El cliente puede tener muchos informes y creo que el punto final para una única administración de informes debe estar anidado de esta manera:

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

En cuanto a todos los informes de un cliente, se espera el enpoint:

/clients/{client_id}/reports

Pero, ¿cómo debería ser un punto final para obtener todos los informes de todos los clientes para mantener la API consistente y bien diseñada?

Mis enfoques:

  1. (Lo vi en alguna API de Google) use "-" en lugar de él y analícelo como "todos":

/clients/-/reports

Esto mantiene el formato de punto final igual, pero parece un poco inusual, no puede encontrar ningún rfc que sugiera de esta manera.

  1. Cree un punto final separado solo para todos los informes:

/reports

Pero para obtener los informes del cliente todavía es:

/clients/{client_id}/reports

  1. Refactorizar puntos finales para hacer que "cliente" no sea un padre, sino solo un parámetro de filtro:

/reports?client={client_id} - informes de un cliente

/reports - informes de todo el cliente

En caso de agregar un nuevo punto final para publicar un informe para un cliente específico, puede parecer feo, porque será una solicitud POST con un parámetro en URL.

¿Hay alguna otra sugerencia de ideas?

Yann
fuente
2
Quizás te interese la pregunta
Laiv

Respuestas:

3

Pero, ¿cómo debería ser un punto final para obtener todos los informes de todos los clientes para mantener la API consistente y bien diseñada?

Antes que nada, recuerde que no hay reglas de oro para modelar API RESTful. Todo lo que tenemos son las mejores prácticas y convenciones. Dicho esto, la respuesta probable es, como de costumbre, elegir la que mejor se adapte a sus necesidades y, en este caso, la que mejor exprese su modelo.

Así que verifique las tres opciones desde la expresividad.

# 1 La notación "-"

Esta es una idea brillante. Nos permite expresar la condición a la reportsque pertenecenclients . Está reduciendo la "consulta" a un conjunto específico de informes (aquellos ubicados dentro del clientslímite).

Mantiene la noción de jerarquía (pertenencia) todo el tiempo, por lo que si reportsse puede encontrar en diferentes ubicaciones, esta notación es muy importante. Por ejemplo:

  • Todos los informes que pertenecen a clientes. /clients/-/reports
  • Todos los informes que pertenecen a los departamentos. /departments/-/reports
  • Todos los informes que pertenecen a los empleados. /employees/-/reports

Sin embargo, para recuperar todos los informes disponibles en el sistema, mantener la jerarquía no proporciona ninguna ventaja valiosa sobre la siguiente opción.

# 2 URI diferentes

Si no necesitamos expresar límites / contextos / jerarquía al momento de recuperar todos los informes disponibles , este enfoque me parece más razonable.

El nuevo URI ( /reports) también deja abierta la posibilidad de una gestión de informes . Sin embargo, no tenemos que proporcionarle un soporte RESTful completo si no lo consideramos necesario. Por ejemplo, usted ha declarado Make a separate endpoint just for all the reports. Eso está bien, solo tiene que implementar GETy quizás algunos filtros para realizar consultas y listo.

Tenga en cuenta que aún podría hacer esto /reports?client={client_id}. Tener diferentes URI para el mismo recurso está bien. Algunos artículos que he leído llamarían a esto robustez .

# 3 Revertir la jerarquía

Tengo la sensación de que este enfoque no cumple con sus expectativas. Además, creo que eventualmente te llevará al punto de partida.

Conclusiones

Tenga en cuenta que # 1 y # 2 no son mutuamente excluyentes. Podemos implementar ambos. Dada la situación real y de acuerdo con las premisas del OP, implementaría solo el # 2.


1: es equivalente a /clients/-/reportssupongo

Laiv
fuente
0

Los patrones de diseño de la API de Google sugieren usar '-' en este escenario.

GET /clients/-/reports

Fuente:

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

wfg4
fuente
2
Lejos de estar en desacuerdo con el todopoderoso Google, pero creo que preferiría algo así /client/{client_id}/report/{report_id}y/clients/report/{report_id}
Robert Harvey
2
@RobertHarvey, ¿por qué no solo /reports?
Laiv
@Laiv: Eso implicaría todos los informes. Actualiza tu página; Hice una edición ninja.
Robert Harvey
@RobertHarvey Quiero decir, ¿por qué no 2 puntos finales diferentes /clients...y /reports.
Laiv
1
@Laiv: OK, pero eso solo plantea la pregunta "¿Qué parámetros debo poner en el cuerpo de la solicitud?"
Robert Harvey