创建 REST API 时使用 Laravel 嵌套动态资源控制器的正确方法
Correct way of nesting dynamic resource controllers with Laravel when creating a REST API
我找到了有关处理嵌套资源控制器和传递多个约束的有用信息,但似乎没有找到任何关于这个特定问题的信息(可能是因为我对它的思考全错了!)。
如果我想在 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(显示所有车的性能)
- /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)并处理代码中的不同路径?
我想你要找的是嵌套资源控制器。这些允许您构建像 /car/1/part/1 这样的路由。此路线将映射到操作 CarPartController@show
并传递两个参数:汽车 ID 和零件 ID。
就 cars/parts 的性能而言,我想说这有点像“显示”方法(因为性能本身不是一个实体)所以会在您的控制器中创建另一个方法,如下所示:
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 文档,必须在资源控制器之前定义非资源方法。
您还可以进一步采用这种方法并实现路由模型绑定,以便将 Car
和 Part
模型的实例注入到您的控制器操作中,而不是 ID:
Route::model('car', 'Car');
Route::model('part', 'Part');
以及控制器操作示例:
public function performance(Car $car, Part $part)
{
// Show performance for specified part on specified car
}
希望对您有所帮助。
我找到了有关处理嵌套资源控制器和传递多个约束的有用信息,但似乎没有找到任何关于这个特定问题的信息(可能是因为我对它的思考全错了!)。
如果我想在 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(显示所有车的性能)
- /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)并处理代码中的不同路径?
我想你要找的是嵌套资源控制器。这些允许您构建像 /car/1/part/1 这样的路由。此路线将映射到操作 CarPartController@show
并传递两个参数:汽车 ID 和零件 ID。
就 cars/parts 的性能而言,我想说这有点像“显示”方法(因为性能本身不是一个实体)所以会在您的控制器中创建另一个方法,如下所示:
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 文档,必须在资源控制器之前定义非资源方法。
您还可以进一步采用这种方法并实现路由模型绑定,以便将 Car
和 Part
模型的实例注入到您的控制器操作中,而不是 ID:
Route::model('car', 'Car');
Route::model('part', 'Part');
以及控制器操作示例:
public function performance(Car $car, Part $part)
{
// Show performance for specified part on specified car
}
希望对您有所帮助。