3、Hyperf3 问答系统 API 开发 - 统一响应数据格式

作者: 温新

图书: 【hyperf 3 实战问答系统接口开发】

阅读: 254

时间: 2024-04-24 12:09:28

hi,我是温新,一名 PHPer

我们的目的是接口开发,因此,保持一个固定的数据响应结构就非常重要,这里我们约定几个响应的格式。

请求失败时,返回

{
    "code": 错误码,
    "message": "Not Found"
}

请求成功时,返回

{
    "code": 0,
    "data": []
}

程序异常时,返回

{
    "code": 错误码, 
    "message": "xxx"
}

格式约定好了之后,下面我们来实现它。

实现统一响应

1)封装统一响应类

app 目录下新建 Components 目录,然后创建一个响应类,如下:

<?php

declare(strict_types=1);

namespace App\Components;


use Hyperf\HttpServer\Contract\ResponseInterface;
use Psr\Container\ContainerInterface;

class Response
{
    protected $container;

    protected $response;

    public function __construct(ContainerInterface $container)
    {
        $this->container = $container;
        $this->response  = $container->get(ResponseInterface::class);
    }


    /**
     * 成功返回方法,用于构建格式化的成功响应数据
     *
     * @param array $data 可选的数据数组,默认为空数组
     * @return \Psr\Http\Message\ResponseInterface
     */
    public function success(array $data = [])
    {
        return $this->response->json([
            'code' => 0,
            'data' => $data
        ]);
    }

    /**
     * 失败返回方法,用于构建格式化的失败响应数据
     *
     * @param int $code 错误代码
     * @param string $message 可选的错误消息,默认为空字符串
     * @return \Psr\Http\Message\ResponseInterface
     */
    public function fail(int $code, string $message = '')
    {
        return $this->response->json([
            'code'    => $code,
            'message' => $message
        ]);
    }
}

2)AbstractController 类中注入 Response 类,修改如下:

<?php

declare(strict_types=1);

namespace App\Controller;

use App\Components\Response;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Contract\RequestInterface;
use Psr\Container\ContainerInterface;

abstract class AbstractController
{
    #[Inject]
    protected ContainerInterface $container;

    #[Inject]
    protected RequestInterface $request;

    # 使用注解构建统一响应
    #[Inject]
    protected Response $response;
}

3)控制器中调用响应类

app/Controller/IndexController.php

<?php

declare(strict_types=1);

namespace App\Controller;
use Hyperf\HttpServer\Annotation\AutoController;
use Hyperf\HttpServer\Contract\RequestInterface;

#[AutoController]
class IndexController extends AbstractController
{
    // ... 表示省略代码
	...

    /**
     * 用于测试响应类
     *
     * @param RequestInterface $request
     * @return \Psr\Http\Message\ResponseInterface
     */
    public function info(RequestInterface $request)
    {
        $id = (int) $request->input('id', 0);

        if ($id > 0) {
            return $this->response->success(['info' => 'success']);
        } else {
            return $this->response->fail(500, 'id无效');
        }
    }
}

4)测试响应类

注意:测试前需要重新启动服务。

当 ID 大于 0 时,响应成功格式;当 ID 小于 0 时,响应失败格式。

$ curl http://127.0.0.1:9501/index/info?id=0
{"code":500,"message":"id无效"}

$ curl http://127.0.0.1:9501/index/info?id=5
{"code":0,"data":{"info":"success"}}

现在,我们已经把统一响应格式封装完成,并通过了测试。但是呢,它还存在一个问题,没有对异常进行处理,一旦使用 throw new \Exception("error");那么就会出现 Internal Server Error.,对于这个问题,下篇文章解决。

请登录后再评论