Попробуйте ресурсы вместо моделей
Посмотрите на ресурсы: https://laravel.com/docs/5.7/eloquent-resources
И добавьте свою логику к ресурсам, чтобы отображать разные версии модели в зависимости от версии API.Вы все еще можете использовать $appends
и $hidden
.
. При таком подходе мы возвращаем Ресурс модели, а не саму модель.
Вот пример UserResource дляразные версии API:
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
}
Теперь, если позже вы захотите переименовать счет в очки в вашей БД, а в V3 вашего API вы также захотите изменить свойВывод 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
});