使用laravel版本api输出的另一种方式?

时间:2018-11-21 15:11:05

标签: laravel api versioning

我要...

  1. 使用Http / Json / V1 / MyModel.php扩展我的App / Orm / MyModel.php,以便可以将$ appends,$ hides,toArray()整齐地藏在V1中
  2. 命名空间并为V1添加一些路由前缀
  3. 可能为路由模型绑定做了一些自定义解析器

我在想...真的吗?他们还没有内置...我在这里想念什么?必须有一个快速的交钥匙。我有兴趣了解其他人的做法,所以请鸣叫。

1 个答案:

答案 0 :(得分:3)

尝试使用资源代替模型

看看资源: 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
}

现在,如果以后您想将score重命名为DB中的点,并且在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
});