Api接口实战:ApiResponse接口统一响应封装

ApiResponse

<?php
namespace App\Helpers;
use App\Enums\ApiCode;
use Illuminate\Support\Facades\Response;

trait ApiResponse
{
    /**
     * @var int
     */
    protected $statusCode = ApiCode::HTTP_OK;

    /**
     * @return mixed
     */
    public function getStatusCode()
    {
        return $this->statusCode;
    }

    /**
     * @param $statusCode
     * @return $this
     */
    public function setStatusCode($statusCode)
    {
        $this->statusCode = $statusCode;
        return $this;
    }

    /**
     * @param $data
     * @param array $header
     * @return mixed
     */
    public function respond($data, $header = [])
    {
        return Response::json($data, $this->getStatusCode(), $header);
    }

    /**
     * @param $status
     * @param array $data
     * @param null $code
     * @return mixed
     */
    public function status($status, array $data, $code = null)
    {
        if ($code) {
            $this->setStatusCode($code);
        }

        $status = [
            'status' => $status,
            'code' => $this->statusCode
        ];

        $data = array_merge($status, $data);
        return $this->respond($data);

    }

    /**
     * @param $message
     * @param int $code
     * @param string $status
     * @return mixed
     */
    public function failed($message, $code = ApiCode::BAD_REQUEST)
    {
        return $this->status('error', [
            'message' => $message,
            'code' => $code
        ]);
    }

    /**
     * @param $message
     * @param string $status
     * @return mixed
     */
    public function message($message, $status = "success")
    {
        return $this->status($status, [
            'message' => $message
        ]);
    }

    /**
     * @param $data
     * @param string $status
     * @return mixed
     */
    public function success($data, $status = "success")
    {
        return $this->status($status, compact('data'));
    }
}

HTTP状态码枚举

<?php
declare(strict_types=1);
namespace App\Enums;
class ApiCode
{
    /**
     * @Message("OK")
     * 对成功的 GET、PUT、PATCH 或 DELETE 操作进行响应。也可以被用在不创建新资源的 POST 操作上
     */
    const HTTP_OK = 200;

    /**
     * @Message("Created")
     * 对创建新资源的 POST 操作进行响应。应该带着指向新资源地址的 Location 头
     */
    const CREATED = 201;

    /**
     * @Message("Accepted")
     * 服务器接受了请求,但是还未处理,响应中应该包含相应的指示信息,告诉客户端该去哪里查询关于本次请求的信息
     */
    const ACCEPTED = 202;

    /**
     * @Message("No Content")
     * 对不会返回响应体的成功请求进行响应(比如 DELETE 请求)
     */
    const NO_CONTENT = 203;

    /**
     * @Message("Moved Permanently")
     * 被请求的资源已永久移动到新位置
     */
    const MOVED_PERMANENTLY = 301;

    /**
     * @Message("Found")
     * 请求的资源现在临时从不同的 URI 响应请求
     */
    const FOUNT = 302;

    /**
     * @Message("See Other")
     * 对应当前请求的响应可以在另一个 URI 上被找到,客户端应该使用 GET 方法进行请求。比如在创建已经被创建的资源时,可以返回 303
     */
    const SEE_OTHER = 303;

    /**
     * @Message("Not Modified")
     * HTTP缓存header生效的时候用
     */
    const NOT_MODIFIED = 304;

    /**
     * @Message("Temporary Redirect")
     * 对应当前请求的响应可以在另一个 URI 上被找到,客户端应该保持原有的请求方法进行请求
     */
    const TEMPORARY_REDIRECT = 307;

    /**
     * @Message("Bad Request")
     * 请求异常,比如请求中的body无法解析
     */
    const BAD_REQUEST = 400;

    /**
     * @Message("Unauthorized")
     * 没有进行认证或者认证非法
     */
    const UNAUTHORIZED = 401;

    /**
     * @Message("Forbidden")
     * 服务器已经理解请求,但是拒绝执行它
     */
    const FORBIDDEN = 403;

    /**
     * @Message("Not Found")
     * 请求一个不存在的资源
     */
    const NOT_FOUND = 404;

    /**
     * @Message("Method Not Allowed")
     * 所请求的 HTTP 方法不允许当前认证用户访问
     */
    const METHOD_NOT_ALLOWED = 405;

    /**
     * @Message("Gone")
     * 表示当前请求的资源不再可用。当调用老版本 API 的时候很有用
     */
    const GONE = 410;

    /**
     * @Message("Unsupported Media Type")
     * 如果请求中的内容类型是错误的
     */
    const UNSUPPORTED_MEDIA_TYPE = 415;

    /**
     * @Message("Unprocessable Entity")
     * 用来表示校验错误
     */
    const UNPROCESSABLE_ENTITY = 422;

    /**
     * @Message("Too Many Requests")
     * 由于请求频次达到上限而被拒绝访问
     */
    const TOO_MANY_REQUESTS = 429;

    /**
     * @Message("Internal Server Error")
     * 服务器遇到了一个未曾预料的状况,导致了它无法完成对请求的处理
     */
    const SERVER_ERROR = 500;

    /**
     * @Message("Not Implemented")
     * 服务器不支持当前请求所需要的某个功能
     */
    const NOT_IMPLEMENTED = 501;

    /**
     * @Message("Bad Gateway")
     * 作为网关或者代理工作的服务器尝试执行请求时,从上游服务器接收到无效的响应
     */
    const BAD_GATEWAY = 502;

    /**
     * @Message("Service Unavailable")
     * 由于临时的服务器维护或者过载,服务器当前无法处理请求。这个状况是临时的,并且将在一段时间以后恢复。如果能够预计延迟时间,那么响应中可以包含一个 Retry-After
     * 头用以标明这个延迟时间(内容可以为数字,单位为秒;或者是一个 HTTP 协议指定的时间格式)。如果没有给出这个 Retry-After 信息,那么客户端应当以处理 500 响应的方式处理它
     */
    const SERVICE_UNAVAILABLE = 503;

    /**
     * @Message("Gateway Timeout")
     */
    const GATEWAY_TIMEOUT = 504;

    /**
     * @Message("HTTP Version Not Supported")
     */
    const HTTP_VERSION_NOT_SUPPORTED = 505;

    /**
     * @Message("Variant Also Negotiates")
     */
    const VARIANT_ALSO_NEGOTIATES = 506;

    /**
     * @Message("Insufficient Storage")
     */
    const INSUFFICIENT_STORAGE = 507;

    /**
     * @Message("Loop Detected")
     */
    const LOOP_DETECTED = 508;

    /**
     * @Message("Not Extended")
     */
    const NOT_EXTENDED = 510;

    /**
     * @Message("Network Authentication Required")
     */
    const NETWORK_AUTHENTICATION_REQUIRED = 511;

    /**
     * @Message("Network Connect Timeout Error")
     */
    const NETWORK_CONNECT_TIMEOUT_ERROR = 599;
}
本作品采用《CC 协议》,转载必须注明作者和本文链接
本帖由系统于 1年前 自动加精
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 11

高产似那啥 :scream:

1年前 评论
ncccc1 1年前

枚举推荐用这个包

1年前 评论
PHPer技术栈 (楼主) 1年前
PHPer技术栈 (楼主) 1年前
还不出来 (作者) 1年前
DogLoML

mark

1年前 评论

这种最好是面向接口,而不是面型实现。不应该使用trait, 正确的做法是使用Facade使用服务提供者实例化。因为一个项目可能,存在不同结构的响应结果,当然我们期望的是一个项目是使用一种响应结果,但事实上往往与期望相差甚远,使用使用Facade使用服务提供者实例化会更灵活。


namespace App\Facades;

use App\Tools\ApiCode;
use App\Tools\Http\HttpCode;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Facade;
use Yc\YcBase\Tools\Http\Response\ResponseInterface;

/**
 * @method static JsonResponse      successForResourcePage(mixed $resource, ?string $msg = null)
 * @method static JsonResponse      successForResource(mixed $resource, ?string $msg = null)
 * @method static JsonResponse      data(mixed $resource, ?string $msg = null)
 * @method static JsonResponse      success(?string $msg = null, mixed $data = null)
 * @method static JsonResponse      successForResourcePageAndGroupBy(mixed $data, string $groupBy, ?string $msg = null)
 * @method static JsonResponse      error(?string $msg = null, string $state = ApiCode::HTTP_BAD_REQUEST, int $httpCode = HttpCode::HTTP_INTERNAL_SERVER_ERROR, $data = null)
 * @method static ResponseInterface setDebug(mixed $debug)
 */
class ApiResponse extends Facade
{
    /**
     * Get the registered name of the component.
     */
    protected static function getFacadeAccessor(): string
    {
        return ResponseInterface::class;
    }
}
class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     */
    public function register(): void
    {
        // bind每次都实例化  singleton单例
        // 前端响应对象
        $this->app->bind(ResponseInterface::class, function () {
            return new ApiResponse();
        });
}
class ApiResponse implements ResponseInterface{
    相关代码
    ......
}
7个月前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!