【问题标题】:Proper RESTful way to create children in Laravel (Parent / Child) relationships在 Laravel(父/子)关系中创建子的正确 RESTful 方式
【发布时间】:2020-10-22 16:24:18
【问题描述】:

不确定这是否特定于 Laravel,但使用 Laravel 创建父级的子级的正确 RESTFUL 方式是什么。例如,我有一辆车可以有很多司机 (hasMany),司机属于一辆车 (belongsTo)。如果我想创建一个父级为 Car #1 的驱动程序,CarController.php 是否有责任创建驱动程序:/car/1/driver/create 还是我使用 /driver/create/car/1 并将责任保留在 DriverController.php 中?

现在我正在做/driver/create/1(其中#1 代表汽车)感觉不对,但我不清楚 RESTFUL 方式应该是什么。 TIA。

【问题讨论】:

    标签: laravel rest


    【解决方案1】:

    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

    针对您关于如何创建驱动程序的问题,我将考虑以下用例;

    1. 创建不与汽车关联的驱动程序
      • POST /drivers
    2. 创建与汽车关联的驱动程序
      • POST /cars/{carId}/drivers
      • POST /drivers

    对于POST /drivers 端点,您将使用DriverController 并将您的Driver 信息传递给store 方法。 store 方法中的验证规则将允许可选的car_id 参数作为请求的一部分。这将允许您在创建时将drivercar 关联或不关联。

    对于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/createGET /drivers/create 找到为给定 car 创建新 driver 的表单。

    听起来关系应该总是有一个单独的控制器。

    理想情况下是的,因为大多数应用程序只不过是 CRUD,因此所有内容都可以映射到 7 个控制器操作之一。这使事情变得干净简单,职责分离。

    看看 Adam Wathan 的 this video,它解释了如何将您认为的自定义操作映射到 7 个基本 Laravel 操作之一。 40 分钟有点长,但值得一看。

    【讨论】:

    • 谢谢你,这很有帮助!对于#2 POST /cars/{carId}/driversstore 端点,这是否使GET /cars/{carId}/drivers/create 成为create 端点?同样对于POST /drivers 创建端点GET /drivers/cars/{carId}?听起来关系应该总是有一个单独的控制器。
    • @JSP 作为回应,我已在我的答案中添加了更新。
    【解决方案2】:

    POST /cars/1/driver。 对指定操作(创建)没有兴趣。方法(post)已经做到了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多