【发布时间】:2019-10-23 22:13:19
【问题描述】:
我正在制作一个 REST API,它将根据正在调用的用户类型返回不同的 JSON 响应。
有一个端点:example.com/api/v1/collect,它使用Laravel's API authentication 来获取带有$user = auth()->guard('api')->user(); 的用户模型。
每个User 都将属于一个Type。
如果User 1 (type_id 1) 拨打电话,响应将如下所示:
{
"example": 1,
"success": true,
"data" : [
...
]
}
如果User 2 (type_id 2) 拨打电话,响应可能会有所不同,具体取决于用户的类型。它可能看起来像:
{
"example": 2,
"response" : [
...
],
"custom": "string",
"success": 200
}
... 是我们发回的数据(例如帖子标题列表),它始终是相同的,但它周围的“信封”(或包装)将特定于每个用户(或用户类型)。
到目前为止,我已经找到了两种解决方案来以抽象的方式包装 ...:
解决方案 1:使用Laravel Blade
// Api\V1\ApiController.php
$data = $user->posts->pluck('title');
// Each type of user will have a different blade filename
// There could be around a 100 types which will result in a 100 blade files
// The filename is stored in the database
$filename = $user->type->filename; // returns 'customBladeTemplate'
// Return a JSON response after passing the $data to the view
return response()->json([
view($filename, compact('data'))->render(),
]);
为每种类型的用户使用刀片文件允许我像这样包装数据:
// resources/views/customBladeTemplate.blade.php
// This filename has to match the one in the database column
{
"example": 1,
"success": true,
"data" : [
{!! $data !!}
]
}
这将为用户 1 输出 JSON 响应(示例 1)
解决方案 2:使用Laravel response macros
// Api\V1\ApiController.php
$data = $user->posts->pluck('title');
// Each type of user will have a different macro name
// There could be around a 100 types which will result in a 100 different macros
// The macro name is stored in the database
$macroName = $user->type->macro_name; // returns 'customMacroName'
return response()->{macroName}($data);
使用数据库中的宏名称为每种类型的用户创建一个宏:
// App\Providers\AppServiceProvider.php
use Illuminate\Http\Response;
public function boot()
{
Response::macro('customMacroName', function ($data) {
return Response::json([
'example' => 2,
'response' => $data,
'custom' => 'string',
'success' => 200,
]);
});
}
该宏将为用户 2 输出 JSON 响应(示例 2)
这两个选项都很好,但我仍然想知道:
- 还有其他(可能更好)方法吗?
- 这两个解决方案是否有效或可以增强?
- 这两种解决方案中哪一种似乎更好,为什么?
编辑: $data 实际上并不是来自一个雄辩的模型,而是来自一个序列化的 JSON 列 (JSON casting) - 这意味着我不能使用 Laravel API resources
【问题讨论】:
-
一开始为什么要这样做?提供基于谁请求的结构似乎有点不自然(而且不是非常 RESTfull)。听起来也像是一场文档噩梦……
-
我已经简化了可读性的问题,但该应用程序实际上是一个 iPaaS(集成平台),它将来自外部 API(即 Magento)的数据映射到其他 API(即 QuickBooks)。每个 API 都有不同的 JSON 输出/输入,可以是 REST、SOAP 或 WebHooks。我必须使 JSON 输出适应每个连接器,同时尽量避免对有效负载进行硬编码,而是尽可能保持“抽象”。这就是为什么我首先选择刀片模板,但我同意,它并不是真正的 RESTful!我只是想不出任何其他解决方案。
标签: php json laravel response laravel-blade