尝试资源而不是模型
查看资源:
https://laravel.com/docs/5.7/eloquent-resources
并将您的逻辑添加到资源中,以便根据 API 版本显示不同版本的模型。您仍然可以使用$appends 和$hidden。
通过这种方法,我们返回模型的资源而不是模型本身。
以下是不同 API 版本的 UserResource 示例:
class UserResource extends JsonResource
{
private $apiVersion;
public function __construct($resource, int $apiVersion = 2) {
$this->apiVersion = $apiVersion; // OPTION 1: Pass API version in the constructor
parent::__construct($resource);
}
public function toArray($request): array
{
// OPTION 2: Get API version in the request (ideally header)
// $apiVersion = $request->header('x-api-version', 2);
/** @var User $user */
$user = $this->resource;
return [
'type' => 'user',
'id' => $user->id,
$this->mergeWhen($this->apiVersion < 2, [
'name' => "{$user->first_name} {$user->last_name}",
], [
'name' => [
'first' => $user->first_name,
'last' => $user->last_name
],
]),
'score' => $user->score,
];
}
}
你可以打电话:
$user = User::find(5);
return new UserResource($user);
如果您需要不同的连接,您可以这样做:
$user = User::on('second_db_connection')->find(5);
所以 V1 API 得到:
{
id: 5,
name: "John Smith",
score: 5
}
而 V2 API 获得:
{
id: 5,
name: {
first: "John",
last: "Smith",
},
score: 5
}
现在,如果稍后您想将分数重命名为数据库中的点,并且在 API 的 V3 中您还想更改 JSON 输出,但保持向后兼容性,您可以这样做:
$this->mergeWhen($this->apiVersion < 3, [
'score' => $user->points,
], [
'points' => $user->points,
])
前缀路线
您可以轻松地为这里提到的路由添加前缀:https://laravel.com/docs/5.7/routing#route-group-prefixes
Route::prefix('v1')->group(function () {
Route::get('users', function () {
// ...
});
});
显式路由模型绑定
要做自定义路由模型绑定看看:https://laravel.com/docs/5.7/routing#route-model-binding
例如
Route::bind('user', function ($value) {
return App\User::where('name', $value)->first() ?? abort(404); // your customer logic
});