sudhanshu-mittal/laravel-api-response

为基于API的项目渲染一致的HTTP JSON响应

dev-master 2022-07-28 20:09 UTC

This package is auto-updated.

Last update: 2024-09-29 01:19:08 UTC


README

Laravel API Response Logo

GitHub Workflow Status Latest Version on Packagist License Total Downloads

Laravel API Response 是一个包,它帮助提供和渲染一致的HTTP JSON响应,同时将异常转换为JSON响应。

版本兼容性

安装

您可以通过composer安装此包

composer require sudhanshu-mittal/laravel-api-response

您可以使用以下命令发布翻译文件

php artisan vendor:publish --tag="api-response-translations"

这将创建一个在项目 lang 文件夹中(如果不存在)的供应商文件夹,并在其中创建一个 api-response/en 文件夹,该文件夹包含两个文件: errors.phpsuccess.php。这两个文件都用于翻译发送的JSON响应中的消息字符串。

可选地,您可以使用以下命令发布配置文件

php artisan vendor:publish --tag="api-response-config"

使用

使用包特性

此包提供了两个特性,可以将它们导入到您的项目中;即

  • \SudhanshuMittal\LaravelApiResponse\Concerns\RendersApiResponse 特性,可以导入到您的(基础)控制器类、中间件类或异常处理器类中
  • \SudhanshuMittal\LaravelApiResponse\Concerns\ConvertsExceptionToApiResponse 特性,应仅导入到异常处理器类中。

因此,我们可以在基础控制器类(所有其他控制器都可能从其中扩展)上

<?php

namespace App\Http\Controllers;

use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Routing\Controller as BaseController;
use SudhanshuMittal\LaravelApiResponse\Concerns\RendersApiResponse;

class Controller extends BaseController
{
  use AuthorizesRequests, DispatchesJobs, ValidatesRequests, RendersApiResponse;
}

或者某个随机的控制器类

<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use SudhanshuMittal\LaravelApiResponse\Concerns\RendersApiResponse;

class RandomController extends Controller
{
  use RendersApiResponse;
}

无论如何,您都可以访问大量方法,可以调用它们来渲染您的数据。这包括

// Successful Responses
return $this->okResponse(
  'This is a random message',
  $data = null,
  $headers = []
);
return $this->createdResponse(
  'This is a random message',
  $data = null,
  $headers = []
);
return $this->acceptedResponse($message, $data, $headers);
return $this->noContentResponse();
return $this->successResponse(
  $message,
  $data = null,
  $status = 200,
  $headers = []
);

// Successful Responses for \Illuminate\Http\Resources\Json\JsonResource
return $this->resourceResponse(
  $jsonResource,
  $message,
  $status = 200,
  $headers = []
);
return $this->resourceCollectionResponse(
  $resourceCollection,
  $message,
  $wrap = true,
  $status = 200,
  $headers = []
);

// Error Responses
return $this->unauthenticatedResponse('Unauthenticated message');
return $this->badRequestResponse('Bad request error message', $error = null);
return $this->forbiddenResponse($message);
return $this->notFoundResponse($message);
return $this->clientErrorResponse(
  $message,
  $status = 400,
  $error = null,
  $headers = []
);
return $this->serverErrorResponse($message);
return $this->validationFailedResponse(
  $validator,
  $request = null,
  $message = null
);

$messages = ['name' => 'Name is not valid'];
$this->throwValidationExceptionWhen($condition, $messages);

还通过在异常处理器中使用 \SudhanshuMittal\LaravelApiResponse\Concerns\ConvertsExceptionToApiResponse 特性来处理异常,该特性提供了 renderApiResponse 公共方法,可以使用以下方式使用

<?php

namespace App\Exceptions;

use App\Traits\HandleApiException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use SudhanshuMittal\LaravelApiResponse\Concerns\ConvertsExceptionToApiResponse;
use Throwable;

class Handler extends ExceptionHandler
{
  use ConvertsExceptionToApiResponse;

  public function render($request, Throwable $e)
  {
    return $this->renderApiResponse($e, $request);
  }
}

您还可以使用处理器的 renderable 方法

<?php

namespace App\Exceptions;

use App\Traits\HandleApiException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use SudhanshuMittal\LaravelApiResponse\Concerns\ConvertsExceptionToApiResponse;
use Throwable;

class Handler extends ExceptionHandler
{
  use ConvertsExceptionToApiResponse;

  public function register()
  {
    $this->renderable(function (Throwable $e, $request) {
      return $this->renderApiResponse($e, $request);
    });
  }
}

使用包类

在上面的方法的核心中,有一个底层的 ApiResponse 类被调用,也可以这样使用

use SudhanshuMittal\LaravelApiResponse\ApiResponse;

$response = new ApiResponse($status = 200, $message = 'Hello world', $data = ['age' => 20], $header = []);

return $response->make();

// Result
{
    "success": true,
    "message": "Hello world",
    "data": {
        'age' => 20
    }
}

// OR
return ApiResponse::create(400, 'Error occurred');

// Result
{
    "success": false,
    "message": "Error occurred"
}

// We could also have
$validator = Validator::make([], ['name' => 'required']);
return ApiResponse::fromFailedValidation($validator);

// Result
{
    "success": true,
    "message": "Validation Failed.",
    "errors": [
        "name": {
            "message": "The name field is required",
            "rejected_value": null
        }
    ]
}

// Also

$response = response()->json(['hello' => 'world']);

return ApiResponse::fromJsonResponse($response, $message = 'Hello');

// Result
{
    "success": true,
    "message": "hello"
    "data": {
        "hello": "world"
    }
}

如果您想更改验证错误的格式,您可以在 App\Providers\AppServiceProvider 类的 boot 方法或其他您想要的任何服务提供程序中调用 ApiResponse 类的 registerValidationErrorFormatter 静态方法。您可以这样做

<?php

// App\Providers\AppServiceProvider

use Illuminate\Contracts\Validation\Validator;
use Illuminate\Http\Request;
use SudhanshuMittal\LaravelApiResponse\ApiResponse;

public function boot()
{
    ApiResponse::registerValidationErrorFormatter(function (Validator $validator, Request $request) {
        return [
            'error_messages' => $validator->errors()->all(),
        ];
    });
}

响应数据

要渲染的成功响应的响应数据 $data 可以是以下类型之一

  • 数组,例如 ['name' => 'Dummy']
  • 标准对象,例如 new stdClass
  • 整数,例如 1
  • 布尔值,例如 true
  • 任何模型对象,instance of \Illuminate\Database\Eloquent\Model
  • 任何集合对象,instance of \Illuminate\Support\Collection
  • 任何JSON资源对象,instance of \Illuminate\Http\Resources\Json\JsonResource
  • 任何可序列化对象,instance of \Illuminate\Contracts\Support\Jsonable
  • 任何可序列化对象,instance of \JsonSerializable
  • 任何可数组对象,instance of \Illuminate\Contracts\Support\Arrayable

以上任何一种都可以存储为 $data 并使用

use SudhanshuMittal\LaravelApiResponse\ApiResponse;

ApiResponse::create(200, 'A message', $data);

对于API资源 JsonResources ,您可以通过以下方式创建JSON响应

use App\Models\Book;
use App\Http\Resources\BookResource;
use App\Http\Resources\BookCollection;
use SudhanshuMittal\LaravelApiResponse\ApiResponse;

$resource = new BookResource(Book::find(1));

return ApiResponse::fromJsonResponse($resource->response(), 'A book');

// Also

$collection = BookResource::collection(Book::all());

return ApiResponse:::fromJsonResponse($collection->response(), 'List of books');

// Also

$collection = new BookCollection(Book::paginate());

return ApiResponse::fromJsonResponse($collection->response, 'Paginated list of books')

响应消息

本包使用翻译文件来翻译在创建响应时定义的消息。如前所述,此包包含两个翻译文件: success.phperrors.php。其中 success.php 包含成功响应消息的翻译,而 errors.php 包含错误响应消息的翻译。

假设您有一个如下的 success.php 翻译文件

<?php

return [
  'Account Created' => 'User account created successfully',
  'invoice_paid' => 'Invoice with number :invoice_number has been paid.',
];

ApiResponse 类能够如下翻译消息

<?php

use SudhanshuMittal\LaravelApiResponse\ApiResponse;

return ApiResponse::create(200, 'Account Created');

// Result
{
    "success": true,
    "message": "User account created successfully"
}

// Also:

return ApiResponse::create(200, 'invoice_paid:invoice_number=INV_12345');

// OR

return ApiResponse::create(200, 'invoice_paid', [
    '_attributes' => ['invoice_number' => 'INV_12345']
]);

// Result
{
    "success": true,
    "message": "Invoice with number INV_12345 has been paid."
}

// Also:

return ApiResponse::create(200, 'invoice_paid', [
    '_attributes' => ['invoice_number' => 'INV_12345'],
    'name' => 'Invoice for Mr Bean',
    'amount' => 1000,
    'number' => 'INV_12345'
]);

// Result
{
    "success": true,
    "message": "Invoice with number INV_12345 has been paid.",
    "data": {
        "name": "Invoice for Mr Bean",
        "amount": 1000,
        "number": "INV_12345"
    }
}

这与错误响应消息的翻译类似,只是错误消息是从 errors.php 翻译文件中读取的(或者您在配置文件中指定的任何文件)。

此外,对于错误消息,您可以决定错误响应应包含错误代码。您可以通过以下几种方式在响应中提供错误代码

<?php

use SudhanshuMittal\LaravelApiResponse\ApiResponse;

return ApiResponse::create(400, 'Error message comes here.', [
    'error_code' => 'request_failed' // The error code here is "request_failed"
]);

// Result
{
    "success": false,
    "message": "Error message comes here.",
    "error_code": "request_failed"
}

此外,您可以使用 errors.php 翻译文件来翻译错误代码。给定以下 errors.php 文件

return [
  'error_code' => [
    'example_code' => 'Just a failed error message',

    'error_code_name' => 'Example error message with status :status',
  ],
];

我们可以有一个如下包含错误代码的响应

<?php

use SudhanshuMittal\LaravelApiResponse\ApiResponse;

return ApiResponse::create(400, 'error_code.example_code');

// Result

{
    "success": false,
    "message": "Just a failed error message",
    "error_code": "example_code"
}

// Also

return ApiResponse::create(400, 'error_code.error_code_name', [
    '_attributes' => ['status' => 'FAILED']
]);

// OR

return ApiResponse::create(400, 'error_code.error_code_name:status=FAILED');

// Result

{
    "success": false,
    "message": "Example error message with status FAILED",
    "error_code": "error_code_name"
}

测试

composer test

更新日志

有关最近更改的更多信息,请参阅 更新日志

贡献

有关详细信息,请参阅 贡献指南

安全漏洞

如果您发现任何与安全相关的问题,请通过电子邮件 mittalsudhanshu29@gmail.com 而不是使用问题跟踪器来报告。

鸣谢

许可协议

MIT 许可协议(MIT)。有关更多信息,请参阅 许可文件