php - 用于 API 响应的 Laravel 自定义包装器

标签 php laravel api lumen fractals

我正在尝试在 Laravel 中构建我的项目刚刚创建以将其用作 back-end API .我想要所有来自 Laravel 的回复将在 JSON:API 中退回官方网站定义的格式:https://jsonapi.org/format/
例如:
我创建了以下2个资源文件:
1- php artisan make:resource User2- php artisan make:resource UserCollection --collection两个简单的资源文件,一个返回一个resource和一个返回 collection .
现在,我想在我的所有回复中返回以下格式:

  • 如果是 success

  • 1- 状态返回码可以是 200 , 201202 .
    2- 返回的响应应类似于以下内容:
    {
        "data": [
            {
                "id": 1,
                "email": "collins.elody@example.org"
            }
        ],
        "message": null,
        "success": true
    }
    
    您可能想知道通过 message 的意义何在?关键,在这种情况下是 null因为它会返回 collection记录,即 阅读 ,但如果您需要 添加 新记录,更新 删除 一,您需要向我的 front-end 传递消息,在这种情况下,我将使用该 key 。
    例如,添加 记录,响应状态码 201 :
    {
        "data": [],
        "message": "Record created succesfully",
        "success": true
    }
    
  • 如果是 failure

  • 正如这里所说:https://jsonapi.org/format/#document-top-level : 成员数据和错误不能共存于同一个文档中。
    因此,如果出现错误,我需要更改 data key 来自 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);
        }
    }
    
    
    但我不确定这是正确的方法,拜托,该领域的技术人员可以帮助我。非常感谢您提前。

    最佳答案

    您走在正确的道路上,我认为有两种主要解决方案可以处理您的确切问题。 FractalEloquent 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 config,有通过spatie发布的 wrapper 。
    转换您的数据,您需要一个转换器。
    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);
    }
    

    关于php - 用于 API 响应的 Laravel 自定义包装器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63081409/

    相关文章:

    php - 检查有效的 SQL 列名

    php - Laravel 5 Eloquent : How to group relationship and get rank

    php - URL 路由 Codeigniter 中的数据范围

    delphi - 如何使用 SQL 以编程方式访问 Windows Live 照片库中的面部识别缓存?

    ios - 来自移动应用程序的 REST API - 使用验证码保护第一次通话是否有意义?

    PHP mysql_query,返回整数而不是资源

    php - doctrine2关联未初始化

    php - 返回数组中的 MySQL 行

    php - Laravel 如何将变量从 php 文件返回到 blade 模板

    javascript - 如何在 react.js 中包含 html View 文件