Mi API tiene dos registros: Coche y Cuenta. Una Cuenta puede tener muchos registros de Automóviles asociados.
Tengo rutas REST para actualizar, eliminar, crear un registro de automóvil.
Normalmente, una ruta GET para llamar a todos los autos se vería así: /car
Una ruta para un auto específico sería /car/:id :id siendo :id del Car.
¿Cómo configuraría una ruta REST para obtener autos de llamada por ID de cuenta? ¿Tendría que hacer algo como account/:id/car ?
Puede hacerlo de forma jerárquica con la ruta URI o usar una cadena de consulta. Creo que el URI RFC cubre esto.
/cars?account=123 /accounts/123/carsA partir de REST puede devolver un hipervínculo con la parte superior, algo así como
{ "operation": "ListCarsAssociatedWithAccount(accountId)", "method": "POST", "URI": "/accounts/{accountId}/cars", "params": {"accountId": {"type":"AccountId"}} } El cliente REST solo debe saber cómo llamar a ListCarsAssociatedWithAccount(accountId) y las plantillas de cuerpo y URI se pueden completar con los parámetros.
Con este enfoque, incluso puede describir el cuerpo de la solicitud POST y la respuesta esperada si lo desea y automatizarlo aún más:
{ "operation": "ListCarsAssociatedWithAccount(accountId, x)", "params": { "accountId": {"type": "AccountId"}, "x": {"type": "Number"} }, "method": "POST", "URI": "/accounts/{accountId}/cars", "body": { "q": { "w": {"param": "x"} } }, "returns": { "type":"CarList", } } ListCarsAssociatedWithAccount(123, 5) -> POST "/accounts/123/cars" { "q": { "w": 5 } } 200 OK { operations: [...], values: [ {"carId": 34, operations: [...]}, {"carId": 3, ...}, {"carId": 4, ...}, ... ] } -> var cl = new CarList(); cl.support(o.operations); var item1 = new Car("carId": o.values[0].carId); item1.support(o.values[0].operations); cl.add(item1) ... return cl;Algo similar (pero mucho más complejo) se usa en el marco de Hydra. http://www.hydra-cg.com/
Los puntos finales se consideran flexibles y baratos de agregar (y modificar manteniendo la compatibilidad con versiones anteriores). Pero normalmente algo como esto:
GET/UPDATE/DELETE: accounts/:id/cars/:carid GET(search)/CREATE: accounts/:id/cars/y también podría obtener la misma información de:
GET/UPDATE/DELETE: cars/:carid GET(search)/CREATE: cars/Tenga en cuenta que en el backend, debería usar la misma lógica para ambos puntos finales (reutilizando el código aquí entre los puntos finales). La idea del primer conjunto de puntos finales es que puede profundizar en elementos específicos de manera lógica/jerárquica. Entonces, si necesita algún subelemento de automóviles para una cuenta específica:
GET/UPDATE/DELETE: accounts/:id/cars/:carid/wheelsEso permite el máximo uso/reutilización de datos sin la necesidad de agregar constantemente filtros basados en cuenta/automóvil en los diversos puntos finales.
NOTA: normalmente, los puntos finales se pluralizarían para que pueda realizar búsquedas desde el mismo punto final, por lo que 'GET /accounts' podría incluir parámetros de búsqueda para recopilar conjuntos de resultados.