在REST 中确实没有实现嵌套资源的正确方法,因为它并不关心。有支持和反对嵌套资源的论据,但是,有一些普遍接受的实现和协议,无论您决定什么,都要保持一致。
我使用嵌套资源,但只有一层嵌套,没有更多。比如:
GET /cars/{carId}/drivers/{driverId}
但是,我会避免以下情况:
GET /cars/{carId}/drivers/{driverId}/incidents
如果有多个嵌套资源,考虑通过父资源获取嵌套资源:
GET /cars/{carId}/drivers/ // Get all drivers for the car
GET /drivers/{driverId}/incidents // Get all incidents for the driver
可以说嵌套资源 URL 比单个资源 URL 一目了然可以传达更多含义。例如
GET /cars/{carId}/drivers/{driverId} // more meaningful
GET /drivers/{driverId} // less meaningful
使用上面的第二个 URL,在资源返回之前,我不知道请求的 driver 与哪个 car 关联。话虽如此,/drivers/{driverId} 仍然适用且有用,具体取决于您的用例。
/drivers 端点的用例是,如果您可以创建尚未与 car 关联的新 drivers。
针对您关于如何创建驱动程序的问题,我将考虑以下用例;
- 创建不与汽车关联的驱动程序
- 创建与汽车关联的驱动程序
POST /cars/{carId}/drivers
POST /drivers
对于POST /drivers 端点,您将使用DriverController 并将您的Driver 信息传递给store 方法。 store 方法中的验证规则将允许可选的car_id 参数作为请求的一部分。这将允许您在创建时将driver 与car 关联或不关联。
对于POST /cars/{carId}/drivers 端点,您将使用CarDriverController(或Cars 子文件夹中的DriverController,如果经常看到)并将Driver 信息传递给store 方法。请求中不需要car_id 参数,因为关联的car 将从URL 中传递的{carId} 获得。
要更新您的 driver 资源,您可以遵循相同的原则,只是修改您的 HTTP 动词并创建适当的路由。
PUT /drivers/{driverId}
DriverController@update
PUT /cars/{carId}/drivers/{driverId}
CarDriverController@update
如果您决定实现这两种方法来创建 drivers 并且发现重复代码,请考虑将其重构为服务。
更新 1
对于#2 POST /cars/{carId}/drivers 是商店端点是否使 GET /cars/{carId}/drivers/create 端点?同样对于 POST /drivers 创建端点 GET /drivers/cars/{carId}?
如果您正在使用刀片视图并遵循 Laravel 约定,那么您可以在 GET /cars/{carId}/drivers/create 或 GET /drivers/create 找到为给定 car 创建新 driver 的表单。
听起来关系应该总是有一个单独的控制器。
理想情况下是的,因为大多数应用程序只不过是 CRUD,因此所有内容都可以映射到 7 个控制器操作之一。这使事情变得干净简单,职责分离。
看看 Adam Wathan 的 this video,它解释了如何将您认为的自定义操作映射到 7 个基本 Laravel 操作之一。 40 分钟有点长,但值得一看。