将 laravel 中的 JsonResponse 进行封装,方便在 api 接口开发时返回固定格式的相应数据。
<?php
namespace AppTraits;
use IlluminateContractsSupportArrayable;
use IlluminateHttpExceptionsHttpResponseException;
use IlluminateHttpJsonResponse;
use IlluminateHttpResourcesJsonJsonResource;
use IlluminateHttpResourcesJsonResourceCollection;
use IlluminatePaginationAbstractPaginator;
use IlluminateSupportArr;
use IlluminateSupportFacadesConfig;
trait JsonResponseTrait
{
/**
* 正确
*
* @param string $message
* @param int $code
* @param array $headers
* @param int $option
* @return JsonResponse
*/
public function ok(string $message = '', int $code = 200, array $headers = [], int $option = 0): JsonResponse
{
return $this->success([], $message, $code, $headers, $option);
}
/**
* 请求已接受响应 状态码 202
*
* @param null $data
* @param string $message
* @param string $location
* @return JsonResponse|JsonResource
*/
public function accepted($data = null, string $message = '', string $location = '')
{
$response = $this->success($data, $message, 202);
if ($location) {
$response->header('Location', $location);
}
return $response;
}
/**
* 已创建响应 状态码 201
*
* @param null $data
* @param string $message
* @param string $location
* @return JsonResponse|JsonResource
*/
public function created($data = null, string $message = '', string $location = '')
{
$response = $this->success($data, $message, 201);
if ($location) {
$response->header('Location', $location);
}
return $response;
}
/**
* 无内容响应 状态码 204
*
* @param string $message
* @return JsonResponse|JsonResource
*/
public function noContent(string $message = '')
{
return $this->success(null, $message, 204);
}
/**
* 错误请求响应 状态码 400
*
* @param string|null $message
*/
public function errorBadRequest(?string $message = ''): void
{
$this->fail($message, 400);
}
/**
* 请求未认证响应 状态码 401
*
* @param string $message
*/
public function errorUnauthorized(string $message = ''): void
{
$this->fail($message, 401);
}
/**
* 请求被禁止响应 状态码 403
*
* @param string $message
*/
public function errorForbidden(string $message = ''): void
{
$this->fail($message, 403);
}
/**
* 资源未找到响应 状态码 404
*
* @param string $message
*/
public function errorNotFound(string $message = ''): void
{
$this->fail($message, 404);
}
/**
* 方法不允许响应 状态码 405
*
* @param string $message
*/
public function errorMethodNotAllowed(string $message = ''): void
{
$this->fail($message, 405);
}
/**
* 服务器错误响应 状态码 500
*
* @param string $message
*/
public function errorInternal(string $message = ''): void
{
$this->fail($message);
}
/**
* 权限认证错误:未注册 状态码 40101
*
* @param string $message
*/
public function errorUnregistered(string $message = ''): void
{
$this->fail($message, 40101);
}
/**
* 失败响应
*
* @param string $message
* @param int $code
* @param array|null $errors
* @param array $header
* @param int $options
*
* @return JsonResponse
* @throws HttpResponseException
*/
public function fail(string $message = '', int $code = 500, mixed $errors = null, array $header = [], int $options = 0)
{
$response = $this->response(
$this->formatData(null, $message, $code, $errors),
Config::get('response.error_code') ?: $code,
$header,
$options
);
if (is_null($errors)) {
$response->throwResponse();
}
return $response;
}
/**
* 成功响应
*
* @param JsonResource|array|null|mixed $data
* @param string $message
* @param int $code
* @param array $headers
* @param int $option
*
* @return JsonResponse|JsonResource
*/
public function success($data = null, string $message = '', int $code = 200, array $headers = [], int $option = 0)
{
if ($data instanceof ResourceCollection) {
return $this->formatResourceCollectionResponse(...func_get_args());
}
if ($data instanceof JsonResource) {
return $this->formatResourceResponse(...func_get_args());
}
if ($data instanceof AbstractPaginator) {
return $this->formatPaginatedResponse(...func_get_args());
}
if ($data instanceof Arrayable) {
$data = $data->toArray();
}
return $this->formatArrayResponse(Arr::wrap($data), $message, $code, $headers, $option);
}
/**
* 格式化数组
*
* @param array|null $data
* @param string $message
* @param int $code
* @param array $headers
* @param int $option
*
* @return JsonResponse
*/
protected function formatArrayResponse(?array $data, string $message = '', $code = 200, array $headers = [], $option = 0): JsonResponse
{
return $this->response($this->formatData($data, $message, $code), $code, $headers, $option);
}
/**
* 格式化数据
*
* @param JsonResource|array|null $data
* @param $message
* @param $code
* @param null $errors
* @return array
*/
protected function formatData($data, $message, &$code, $errors = null): array
{
$originalCode = $code;
$code = (int) substr($code, 0, 3); // notice
if ($code >= 400 && $code <= 499) {// client error
$status = 'error';
} elseif ($code >= 500 && $code <= 599) {// service error
$status = 'fail';
} else {
$status = 'success';
}
if (! $message && class_exists($enumClass = Config::get('response.enum'))) {
$message = $enumClass::fromValue($originalCode)->description;
}
return [
'status' => $status,
'code' => $originalCode,
'message' => $message,
'data' => $data ?: (object) $data,
'error' => $errors ?: (object) [],
];
}
/**
* 格式化分页信息
*
* @param AbstractPaginator $resource
* @param string $message
* @param int $code
* @param array $headers
* @param int $option
*
* @return mixed
*/
protected function formatPaginatedResponse($resource, string $message = '', $code = 200, array $headers = [], $option = 0)
{
$paginated = $resource->toArray();
$paginationInformation = $this->formatPaginatedData($paginated);
$paginationDataField = Config::get('response.format.paginated_resource.data_field', 'items');
$data = array_merge_recursive([$paginationDataField => $paginated['data']], $paginationInformation);
return $this->response($this->formatData($data, $message, $code), $code, $headers, $option);
}
/**
* 格式化分页数据
*
* @param array $paginated
*
* @return array
*/
protected function formatPaginatedData(array $paginated)
{
$count = $paginated['total'] ?? null;
$totalPages = $paginated['last_page'] ?? null;
$previous = $paginated['prev_page_url'] ?? null;
$next = $paginated['next_page_url'] ?? null;
$paginationInformation = [
'meta' => [
'pagination' => [
'count' => $paginated['to'] ?? null,
'per_page' => $paginated['per_page'] ?? null,
'current_page' => $paginated['current_page'] ?? null,
],
],
];
if (!is_null($count)) {
$paginationInformation['meta']['pagination']['total'] = $count;
}
if ($totalPages) {
$paginationInformation['meta']['pagination']['total_pages'] = $totalPages;
}
if ($previous || $next) {
$paginationInformation['meta']['pagination']['links'] = [
'previous' => $previous,
'next' => $next,
];
}
return $paginationInformation;
}
/**
* 格式化集合
*
* @param JsonResource $resource
* @param string $message
* @param int $code
* @param array $headers
* @param int $option
*
* @return mixed
*/
protected function formatResourceCollectionResponse($resource, string $message = '', $code = 200, array $headers = [], $option = 0)
{
$dataField = 'items';
$data = array_merge_recursive([$dataField => $resource->resolve(request())], $resource->with(request()), $resource->additional);
if ($resource->resource instanceof AbstractPaginator) {
$paginated = $resource->resource->toArray();
$paginationInformation = $this->formatPaginatedData($paginated);
$data = array_merge_recursive($data, $paginationInformation);
}
return tap(
$this->response($this->formatData($data, $message, $code), $code, $headers, $option),
function ($response) use ($resource) {
$response->original = $resource->resource->map(
function ($item) {
return is_array($item) ? Arr::get($item, 'resource') : $item->resource;
}
);
$resource->withResponse(request(), $response);
}
);
}
/**
* 格式化Resource
*
* @param JsonResource $resource
* @param string $message
* @param int $code
* @param array $headers
* @param int $option
*
* @return mixed
*/
protected function formatResourceResponse($resource, string $message = '', $code = 200, array $headers = [], $option = 0)
{
$resourceData = array_merge_recursive($resource->resolve(request()), $resource->with(request()), $resource->additional);
return tap(
$this->response($this->formatData($resourceData, $message, $code), $code, $headers, $option),
function ($response) use ($resource) {
$response->original = $resource->resource;
$resource->withResponse(request(), $response);
}
);
}
/**
* 基本响应
*
* @param mixed $data
* @param int $status
* @param array $headers
* @param int $options
* @return JsonResponse
*/
protected function response($data = [], $status = 200, array $headers = [], $options = 0): JsonResponse
{
return new JsonResponse($data, $status, $headers, $options);
}
}
想要了解更多内容,请持续关注码农资源网,一起探索发现编程世界的无限可能!
本站部分资源来源于网络,仅限用于学习和研究目的,请勿用于其他用途。
如有侵权请发送邮件至1943759704@qq.com删除
码农资源网 » Laravel api json response 封装
本站部分资源来源于网络,仅限用于学习和研究目的,请勿用于其他用途。
如有侵权请发送邮件至1943759704@qq.com删除
码农资源网 » Laravel api json response 封装