Al diseñar un servicio web RESTful, ¿se debe diseñar la API para que funcione la ID de las cadenas de valores que se transmiten de un lado a otro entre el servidor?
Aquí hay un ejemplo: Digamos que tengo un recurso de empleado, que tiene un estado y atributos de género. En la base de datos Estado y género y tablas separadas y, por lo tanto, objetos de dominio separados, cada uno con su propio identificador.
Digamos la solicitud del cliente / empleado / 1. El servidor podría devolver algo como esto ...
Caso 1:
{
"id": 1,
"firstName": "Jane",
"lastName": "Doe",
"active": true,
"gender": {
"id": 1,
"gender": "FEMALE"
},
"status": {
"id": 3,
"status": "FULL_TIME"
}
}
Caso 2:
{
"id": 1,
"firstName": "Jane",
"lastName": "Doe",
"active": true,
"gender": "FEMALE",
"status": "FULL_TIME"
}
Caso 3:
{
"id": 1,
"firstName": "Jane",
"lastName": "Doe",
"active": true,
"genderId": 1,
"statusId": 3
}
El caso 3 parece tener menos sentido ya que el cliente no tiene idea de qué género es el Id. 1 a menos que se dé la vuelta y realice otra llamada al servidor para obtener esos datos.
Sin embargo, ahora digamos que el cliente está actualizando al usuario a través de:
PUT /employee/1
¿Debería la solicitud Payload usar los identificadores o una cadena? De cualquier manera, el back-end tiene que buscarlos para asegurarse de que sean válidos, pero es mejor trabajar con ID sobre Strings.
fuente
El caso 2 es la única opción real. Ya ha señalado los problemas con el Caso 3. El Caso 1 proporciona información que al cliente de la API no le interesa (los ID internos para los estados, por ejemplo), y requiere que el cliente sepa sobre aquellos para construir una solicitud PUT . Sí, la solicitud PUT es un poco más breve si puede usar las ID en lugar de las cadenas completas, pero especificar "FULL_TIME" o "PART_TIME" es lo que el cliente sabe, no es que tengan algunas ID arbitrarias en su base de datos. .
Por supuesto, puede documentar los ID en la documentación de su API, pero es igual de fácil documentar los valores válidos que las cadenas pueden ser, y probablemente más claros.
fuente
Los datos enumerados como los que tiene aquí son altamente almacenables en caché. Use enlaces en lugar de objetos. Utilice los encabezados de almacenamiento en caché para permitir a los clientes almacenar en caché los géneros y estados localmente, por ejemplo, durante 24 horas. Entonces solo la primera llamada del día sale de la máquina del cliente. Probablemente también pueda configurar el almacenamiento en caché para permitir que los servidores intermedios retengan la información, por lo que algunas solicitudes de clientes ni siquiera llegan a su servidor.
Una desventaja es que
/genders/1
no es legible para los humanos. En su lugar/genders/female
, puede usar , pero luego no puede cambiar el nombre de un género sin romper clientes. Esa es la clave sintética frente a la compensación de la clave natural: flexibilidad frente a legibilidad humana.Es posible que también desee considerar poner todas sus listas de valores en un punto final común, como
Esto aclarará a los clientes que todos son básicamente pares clave-valor que pertenecen a diferentes agrupaciones.
fuente
Iría por algo entre 1 y 2, por las razones que David mencionó:
No desea exponer la identificación de las cosas a menos que sea necesario.
Sin embargo, exponer la ID podría ser necesario en algún momento. Si eso sucede, la compatibilidad con versiones anteriores es una preocupación. Entonces, haría esto:
Que tiene las mismas propiedades que tiene la opción 2; pero tiene el beneficio de que agregar la ID más adelante no introduce una interrupción de BC:
Como Eric señala en los comentarios, esto todavía usa el nombre de la entidad como un identificador único. Si la identificación se introduce más tarde, el nombre debe seguir siendo el mismo porque los clientes más antiguos podrían (o más bien lo habrían hecho) codificado.
fuente
name
usaría para consultar y actualizar.id
como identificador único, entonces ese es un cambio radical.