创建 REST API 时使用 Laravel 嵌套动态资源控制器的正确方法

Posted

技术标签:

【中文标题】创建 REST API 时使用 Laravel 嵌套动态资源控制器的正确方法【英文标题】:Correct way of nesting dynamic resource controllers with Laravel when creating a REST API 【发布时间】:2015-05-29 03:10:03 【问题描述】:

我找到了有关处理嵌套资源控制器和传递多个约束的好信息,但似乎在这个特定问题上一无所获(可能是因为我想的全错了!)。

如果我想在我的 API 中创建以下内容

/cars(显示所有汽车) /cars/1(显示 carId = 1) /cars/1/performance(显示 carId=1 的性能) /cars/1/performance/parts(显示 carId=1 的部件性能) /cars/1/performance/parts/1(显示 partId=1 for carId=1 的性能) /cars/performance(显示所有汽车的性能) /汽车/性能/零件 /零件 /parts/1 等...(与上述汽车的零件相同)

我是否必须以这种方式为大多数路由和控制器创建路由和控制器

Route::group(array('prefix' => 'myAwesomeCarApi'), function()

    Route::resource('cars', 'CarsController'); 
    Route::resource('cars/performance', 'CarsPerController');
    Route::resource('cars/performance/parts', 'CarsPerPartsController');
    Route::resource('cars.performance/parts', 'CarsPerPartsController');
    Route::resource('parts', 'PartsController');
    Route::resource('parts/performance', 'PartsPerController');
    etc...
);

或者我在创建动态控制器时缺少一些技巧,例如只有 3 个(CarController、PartsController、PerformanceController)和处理代码中的不同路由?

【问题讨论】:

【参考方案1】:

我认为您正在寻找的是嵌套资源控制器。这些允许您构建像 /car/1/part/1 这样的路线。该路线将映射到动作 CarPartController@show 并传递两个参数:汽车 ID 和零件 ID。

就汽车/零件的性能而言,我会说这有点像“展示”方法(因为性能本身并不是一个实体),所以会在您的控制器中创建另一个方法,如下所示:

class CarPartController extends Controller 

    public function show($carId, $partId)
    
        // Show specified part for specified car
    

    public function performance($carId, $partId)
    
        // Show the performance for specified part on specified car
    


那么您的路线将如下所示:

Route::get('car/car/performance', 'CarController@performance');
Route::get('car/car/part/part/performance', 'CarPartController@performance');

Route::resource('car', 'CarController');
Route::resource('car/car/part', 'CarPartController');

根据 Laravel 文档,非资源方法必须在资源控制器之前定义。

您还可以进一步采用这种方法并实现路由模型绑定,以便将 CarPart 模型的实例注入控制器操作而不是 ID:

Route::model('car', 'Car');
Route::model('part', 'Part');

还有一个示例控制器操作:

public function performance(Car $car, Part $part)

    // Show performance for specified part on specified car

希望这会有所帮助。

【讨论】:

谢谢,太好了,正是我需要的。当您第一次开始使用路由、mvc 和 REST api 时,有很多概念需要您了解,因此有时应用它们可能会令人困惑! 我想我的后续问题是这如何或是否符合 REST 原则,因为一旦我开始使用 Route::get('car/car/performance', 'CarController@performance');我是不是在远离严格的 GET/PUT/DELETE 等 REST 原则 包含通配符的段不用添加,可以这样写:Route::resource('car.part', 'CarPartController'); @cdarken 这不是通配符。这是一个路由参数。 @MartinBean 你是对的。如果您使用点,该参数将自动生成。

以上是关于创建 REST API 时使用 Laravel 嵌套动态资源控制器的正确方法的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Laravel 5.3 创建 REST 完整 Web 服务的 Api

如何在 laravel 中使用社交名流和护照创建 REST API

如何在 Laravel 中为 REST API 创建身份验证

Laravel 7 - 使用 REST API 而不是数据库

laravel Passport - 创建 REST API 用户认证以及Dingo/Api v2.0+Passport实现api认证

REST API 的 Laravel DB 查询非常慢