用于 API 响应的 Laravel 自定义包装器
Posted
技术标签:
【中文标题】用于 API 响应的 Laravel 自定义包装器【英文标题】:Laravel Custom Wrapper for API Responses 【发布时间】:2020-11-14 18:46:34 【问题描述】:我正在尝试在刚刚创建的Laravel
中构建我的项目,以将其用作back-end API
。我希望以官方网站上定义的JSON:API
格式返回来自Laravel
的所有回复:https://jsonapi.org/format/
例如: 我创建了以下 2 个资源文件:
1-php artisan make:resource User
2-php artisan make:resource UserCollection --collection
两个简单的资源文件,一个返回resource
,一个返回collection
。
现在,我想在我的所有回复中返回以下格式:
如果是success
1-状态返回码可以是200
、201
或202
。
2- 返回的响应应该类似于以下内容:
"data": [
"id": 1,
"email": "collins.elody@example.org"
],
"message": null,
"success": true
您可能想知道传递message
键有什么意义,在本例中是null
,因为它将返回一个collection
记录,即读取 ,但如果您需要添加新记录、更新或删除一条记录,则需要将消息传递给我的front-end
,在这种情况下,我会使用该密钥。
示例,添加记录,响应状态码201
:
"data": [],
"message": "Record created succesfully",
"success": true
如果是failure
如这里所说:https://jsonapi.org/format/#document-top-level:成员数据和错误不能共存于同一个文档中。
所以,如果出现错误,我需要将data
密钥更改为errors
密钥,例如,假设我正在尝试验证自己,并且验证失败,在这种情况下,结果应该是这样的:
"errors":
"email": "E-Mail is required",
"password": "Password is required"
,
"message": null,
"success": false
或者我只想返回一个error message
,预期的输出应该是:
"errors": [],
"message": "Something is Wrong!",
"success": false
所以本质上,我需要的是一个全局包装器,用于我从 Laravel 中做出的所有响应。我想以一种优雅的方式调用 return 如下:
return $this->success($collection);
或
return $this->success('Done!', 201);
所以首先想到的是创建一个trait
并定义您需要的方法,然后从Laravel
中的任何位置调用它们
我的Trait
<?php
namespace App\Traits;
trait APIResponse
public function success($data, $status = 200)
return [
'data' => $data,
'success' => in_array($status, [200, 201, 202]) ? true : false,
'message' => null
];
public function failure($data, $status = 500)
// TODO
我的Controller
class ExampleController extends Controller
public function index()
$collection = new UserCollection(User::all());
return $this->success($collection);
但我不确定这是正确的方法,请在该领域的技术人员可以帮助我。非常感谢您。
【问题讨论】:
【参考方案1】:您走在正确的道路上,我认为有两种主要解决方案是处理您的确切问题的最佳方法。 Fractal 和 Eloquent Resources,由于一些设计决策和经验,我更喜欢 Fractal。
我将展示一个分形示例,使用wrapper by Spatie。首先创建一个序列化器,它将按预期包装数据。
class YourCustomSerializer extends SerializerAbstract
public function collection($resourceKey, array $data)
return [
$resourceKey ?: 'data' => $data,
'message': null,
'success': true,
];
public function item($resourceKey, array $data)
return [
$resourceKey ?: 'data' => $data,
'message': null,
'success': true,
];
这应该添加到您的 fractal.php
配置中,通过 spatie
包装器发布。
转换数据需要转换器。
class UserTransformer extends TransformerAbstract
public function transform(User $user)
return [
'name' => $user->name,
'email' => $user->email,
];
现在您可以将数据转换为预期的格式。
public function response($data, int $statusCode = Response::HTTP_OK)
return fractal($data, $this->transformer)->respond($statusCode);
对于错误代码,您应该转到Handler.php
并添加与此类似的内容。这是一种非常幼稚的做法,但要知道应该让您继续进行错误处理,您需要对验证异常、状态代码等做一些事情。
if ($request->wantsJson())
return response()->json([
'success' => false,
'message' => $exception->getMessage(),
], Response::HTTP_BAD_REQUEST);
【讨论】:
我不会做“添加记录”或类似的具体消息,这是浪费时间,只依赖成功真实或类似 关于 json api 规范,请记住这是一个非常自以为是的规范,它为了结构而添加了很多结构,参数始终是您可以使用客户端或类似的方式来使用您的 API练习到目前为止我从未见过。我认为你基于这个问题有多远,你需要找到自己的做和不做的路径。你以某种方式同意结构很好的规范,只是把它变成你自己的。 哇! @mrhn,感谢您的详细解释,我一直在阅读有关 Fractal 包的信息,但我从未阅读过它,因为我到目前为止已经阅读过,它在 Laravel 5.5 版之前使用,因为它使这种工作变得更加容易。我会尝试使用 Eloquent Resources,因为这是 Laravel 处理此类问题的官方方式……如果没有得到结果,我保证我会尝试 Fractal,然后我会告诉你我的经验。再次......一百万谢谢你给我的问题一个北方。- 幸运的是方法是相似的,你 EloquentResources 没有与序列化程序类似的概念以上是关于用于 API 响应的 Laravel 自定义包装器的主要内容,如果未能解决你的问题,请参考以下文章
Laravel 5 - 在 Rest API 服务器上自定义 JSON 响应
如何自定义 laravel api 的 json 响应并在 vuex 中显示它们