[英]How to create CRUD API for a table with compose primary keys
I have a Laravel application to serving CRUD APIs.我有一个 Laravel 应用程序来提供 CRUD API。 There is a table with compose primary keys and I introduced the keys in the model as well as in the migration file:
有一个包含组合主键的表,我在模型和迁移文件中引入了这些键:
protected $primaryKey = ['personel_id', 'valid_for_quarter'];
Also I defined its route like this:我也这样定义了它的路线:
Route::middleware('auth:api')->group( function () {
Route::apiResources([
'peopleDatas' => 'API\PeopleDataController'
]);
});
and the controller class that contains show
method like this:和包含
show
方法的控制器类,如下所示:
public function show(PeopleData $peopleData)
{
dd($peopleData);
}
now the questions are:现在的问题是:
1. What is the url for accessing the show method in this case when the object has multiple primary keys? 1.当对象有多个主键时,这种情况下访问show方法的url是什么? Please notice that I didn't defined the route url by myself explicitly and I want to use
Route::apiResources
method.请注意,我没有自己明确定义路由 url,我想使用
Route::apiResources
方法。 Is it possible?是否可以?
Here is the routes list:以下是路线清单:
| | GET|HEAD | api/peopleDatas | peopleDatas.index | App\Http\Controllers\API\PeopleDataController@index | api,auth:api |
| | POST | api/peopleDatas | peopleDatas.store | App\Http\Controllers\API\PeopleDataController@store | api,auth:api |
| | GET|HEAD | api/peopleDatas/{peopleData} | peopleDatas.show | App\Http\Controllers\API\PeopleDataController@show | api,auth:api |
| | DELETE | api/peopleDatas/{peopleData} | peopleDatas.destroy | App\Http\Controllers\API\PeopleDataController@destroy | api,auth:api |
| | PUT|PATCH | api/peopleDatas/{peopleData} | peopleDatas.update | App\Http\Controllers\API\PeopleDataController@update | api,auth:api |
In other hand should I define the urls in this case explicitly?另一方面,我应该在这种情况下明确定义网址吗? for example
/api/peopleDatas/{key1}/{key2}
or is there any standard way for it that applies by Laravel?例如
/api/peopleDatas/{key1}/{key2}
或者是否有任何适用于 Laravel 的标准方法?
2. If the object has multiple primary keys does the Eloquent
and Laravel Route Model Binding can handle it and fetch the item from the DB or I need to take the ids from user and apply the find
function on my model? 2.如果对象有多个主键做的
Eloquent
和Laravel路由模型绑定可以处理它,并获取从数据库中的项目或我需要从用户采取id和应用find
在我的模型功能?
3. If it does not handle by Laravel itself by default is it possible to override some functions to tell Laravel how to fetch the item from DB in case of Route Model Binding
? 3.如果默认情况下它不由 Laravel 自己处理,是否可以覆盖一些函数来告诉 Laravel 在
Route Model Binding
情况下如何从数据库中获取项目?
Is there a reason you cannot have a single unique value such as an auto-increment ID as the primary key then have the two additional indexes as a unique composite index?是否有原因不能将单个唯一值(例如自动增量 ID)作为主键,然后将两个附加索引作为唯一复合索引?
This would solve your route parameter issue as you would only have a single primary key:这将解决您的路由参数问题,因为您只有一个主键:
/api/peopleDatas/{id}
Your migration would include the specification of a unique composite index:您的迁移将包括唯一复合索引的规范:
$table->unique(['personel_id', 'valid_for_quarter']);
That way your combined columns maintain uniqueness while your route is simplified to a single ID and your relationships can use a single ID also.这样,您的组合列保持唯一性,同时您的路线被简化为单个 ID,并且您的关系也可以使用单个 ID。 This will improve performance and well as simplify the code.
这将提高性能并简化代码。
Alternatively if you absolutely MUST have a composite primary key you could do so.或者,如果你绝对必须有一个复合主键,你可以这样做。 Your migration would require:
您的迁移需要:
$table->primary(['personel_id', 'valid_for_quarter']);
Your model would need keys set for the save query (see link) https://blog.maqe.com/solved-eloquent-doesnt-support-composite-primary-keys-62b740120f您的模型需要为保存查询设置键(见链接) https://blog.maqe.com/solved-eloquent-doesnt-support-composite-primary-keys-62b740120f
protected function setKeysForSaveQuery(Builder $query)
{
$query
->where('personel_id', '=', $this->getAttribute('personel_id'))
->where('valid_for_quarter', '=', $this->getAttribute('valid_for_quarter'));
return $query;
}
And the best solution for the route binding would be to employ explicit route model binding (see link to docs) with your parameter being a delimited combination of your two keys:路由绑定的最佳解决方案是使用显式路由模型绑定(参见文档链接),您的参数是两个键的分隔组合:
/api/peopleDatas/{people_data}
where people data = 1_3
for example /api/peopleDatas/{people_data}
其中人员数据 = 1_3
例如
https://laravel.com/docs/5.8/routing#explicit-binding https://laravel.com/docs/5.8/routing#explicit-binding
In your route service provider you would need to specify the resolution logic which would be something like:在您的路线服务提供商中,您需要指定解析逻辑,类似于:
public function boot()
{
parent::boot();
Route::bind('people_data', function ($value) {
return App\PeopleData::where('personal_id', explode('_', $value)[0])
->where('valid_for_quarter', explode('_', $value)[1])
->first() ?? abort(404);
});
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.