¿Cuáles son las mejores prácticas para los recursos anidados REST?

Resuelto Wes asked hace 10 años • 8 respuestas

Por lo que puedo decir, cada recurso individual debería tener solo una ruta canónica . Entonces, en el siguiente ejemplo, ¿cuáles serían buenos patrones de URL?

Tomemos, por ejemplo, una representación restante de Empresas. En este ejemplo hipotético, cada empresa posee 0 o más departamentos y cada departamento posee 0 o más empleados.

Un departamento no puede existir sin una empresa asociada.

Un empleado no puede existir sin un departamento asociado.

Ahora encontraría que la representación natural de los patrones de recursos es.

  • /companies Un conjunto de empresas : acepta POST para una nueva empresa. Consigue toda la colección.
  • /companies/{companyId}Una empresa individual. Acepta GET, PUT y DELETE
  • /companies/{companyId}/departmentsAcepta POST para un artículo nuevo. (Crea un departamento dentro de la empresa).
  • /companies/{companyId}/departments/{departmentId}/
  • /companies/{companyId}/departments/{departmentId}/employees
  • /companies/{companyId}/departments/{departmentId}/employees/{empId}

Dadas las limitaciones de cada una de las secciones, creo que esto tiene sentido aunque esté un poco profundamente anidado.

Sin embargo, mi dificultad surge si quiero enumerar ( GET) todos los empleados de todas las empresas.

El patrón de recursos para eso se correspondería más estrechamente con /employees(La colección de todos los empleados)

¿Eso significa que debería haberlo hecho /employees/{empId}también porque, de ser así, hay dos URI para obtener el mismo recurso?

O tal vez todo el esquema debería aplanarse, pero eso significaría que los empleados son un objeto anidado de nivel superior.

En un nivel básico, /employees/?company={companyId}&department={deptId}devuelve exactamente la misma vista de los empleados que el patrón más anidado.

¿Cuál es la mejor práctica para los patrones de URL en los que los recursos pertenecen a otros recursos pero deberían poder consultarse por separado?

Wes avatar Jan 06 '14 20:01 Wes
Aceptado

Probé ambas estrategias de diseño: puntos finales anidados y no anidados. He encontrado que:

  1. Si el recurso anidado tiene una clave principal y usted no tiene su clave principal principal, la estructura anidada requiere que la obtenga, aunque el sistema en realidad no la requiera.

  2. Los puntos finales anidados normalmente requieren puntos finales redundantes. En otras palabras, la mayoría de las veces necesitará el punto final /employees adicional para poder obtener una lista de empleados en todos los departamentos. Si tiene /empleados, ¿qué le compra exactamente /empresas/departamentos/empleados?

  3. Los puntos finales de anidación no evolucionan tan bien. Por ejemplo, es posible que no necesite buscar empleados ahora, pero podría hacerlo más adelante y, si tiene una estructura anidada, no tendrá más opción que agregar otro punto final. Con un diseño no anidado, simplemente agrega más parámetros, lo cual es más simple.

  4. A veces un recurso puede tener varios tipos de padres. Lo que da como resultado que varios puntos finales devuelvan el mismo recurso.

  5. Los puntos finales redundantes hacen que los documentos sean más difíciles de escribir y también hace que la API sea más difícil de aprender.

En resumen, el diseño no anidado parece permitir un esquema de punto final más flexible y simple.

Patc avatar Apr 04 '2016 19:04 Patc

Lo que has hecho es correcto. En general, puede haber muchos URI para el mismo recurso; no existen reglas que indiquen que no se debe hacer eso.

Y, en general, es posible que necesite acceder a los elementos directamente o como un subconjunto de otra cosa, por lo que su estructura tiene sentido para mí.

Sólo porque los empleados son accesibles en el departamento:

company/{companyid}/department/{departmentid}/employees

No significa que no se pueda acceder a ellos también desde la empresa:

company/{companyid}/employees

Lo cual devolvería empleados a esa empresa. Depende de lo que necesite su cliente consumidor; para eso debería diseñar.

Pero espero que todos los controladores de URL utilicen el mismo código de respaldo para satisfacer las solicitudes y no duplicar el código.

jeremyh avatar Oct 15 '2014 17:10 jeremyh

Moví lo que hice de la pregunta a una respuesta donde es probable que más personas la vean.

Lo que he hecho es tener los puntos finales de creación en el punto final anidado. El punto final canónico para modificar o consultar un elemento no está en el recurso anidado .

Entonces, en este ejemplo (solo enumera los puntos finales que cambian un recurso)

  • POST /companies/crea una nueva empresa y devuelve un enlace a la empresa creada.
  • POST /companies/{companyId}/departmentscuando se coloca un departamento crea el nuevo departamento devuelve un enlace a/departments/{departmentId}
  • PUT /departments/{departmentId}modifica un departamento
  • POST /departments/{deparmentId}/employeescrea un nuevo empleado y devuelve un enlace a/employees/{employeeId}

Entonces hay recursos de nivel raíz para cada una de las colecciones. Sin embargo, la creación está en el objeto propietario .

Wes avatar Sep 28 '2015 10:09 Wes