基于Laravel的response中间件

前言

新项目开始了,做了一些基础配置。

因为这个项目的定位是 api服务(虽然我不理解为什么小伙伴们这么崇尚 Laravel,嫌弃 Lumen),所以需要统一响应信息。

正常响应

为了能够统一响应信息,这里准备写一个 Response中间件

原理就不说明了,一张图帮助理解(我懒)。

图片来自网络

1、创建文件 app/Http/Middleware/FormaterResponse.php

也可以用 php artisan make:middleware 创建。

2、填充内容,这里给个简单的示例,具体业务逻辑自行填充

<?php

namespace App\Http\Middleware;

use Closure;

class FormaterResponse
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * 
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $response = $next($request);
        if ($response->getStatusCode() == 200) {
            $response->setData([
                'code' => 200,
                'data' => $response->getData()
            ]);
        }
        return $response;
    }
}

3、注册中间件

编辑文件 app/Http/Kernel.php

Lumen 用户找注册中间件的地方,手动添加即可。

<?php

namespace App\Http;

use Illuminate\Foundation\Http\Kernel as HttpKernel;

class Kernel extends HttpKernel
{
    /**
     * The application's global HTTP middleware stack.
     *
     * These middleware are run during every request to your application.
     *
     * @var array
     */
    protected $middleware = [
        // ...
        \App\Http\Middleware\FormaterResponse::class,
    ];
    
    // ...
}

4、试试看吧

异常响应

正常响应是有了,异常响应呢?

Laravel 是帮我们封装了一下,还是自己弄的舒服不是。

找到文件 app/Exceptions/Handler.php,重写一下 render

<?php

namespace App\Exceptions;

use Throwable;
use Illuminate\Validation\ValidationException;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

class Handler extends ExceptionHandler
{
    /**
     * A list of the exception types that are not reported.
     *
     * @var array
     */
    protected $dontReport = [
        AuthorizationException::class,
        HttpException::class,
        ModelNotFoundException::class,
        ValidationException::class
    ];
    
    // ...

    /**
     * Render an exception into an HTTP response.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Throwable  $exception
     * @return \Symfony\Component\HttpFoundation\Response
     *
     * @throws \Throwable
     */
    public function render($request, Throwable $exception)
    {
        switch (true) {
            case $exception instanceof NotFoundHttpException:
                return response([
                    'code' => $exception->getStatusCode(),
                    'msg' => 'Not Found'
                ], $exception->getStatusCode());

            case $exception instanceof HttpResponseException:
                return $exception->getResponse();

            case $exception instanceof ValidationException:
                $response = $exception->getResponse();
                $message  = null;
                foreach ($exception->errors() as $messages) {
                    $message = current($messages);
                    break;
                }
                if (!$response) {
                    return response([
                        'code' => 422,
                        'msg'  => $message ?? 'validation_failed',
                    ], 422);
                }
                $response->setData(
                    [
                        'code' => $response->getStatusCode(),
                        'msg'  => $message ?? 'validation_failed',
                    ]
                );
                return $response;

            default:
                return response(['code' => 500, 'msg' => $exception->getMessage()], 500);
        }
    }
}

当然,也可以在中间件中处理。

简洁的Controller

<?php

namespace App\Http\Controllers;

class AccountController extends Controller
{
    public function show($id)
    {
        if ($id == 1) {
            throw new \Exception('sth error');
        }

        return [
        	'id' => $id
        ];
    }
}

最后

框架中的一些设计会帮我们省很多事,好好利用,真香。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!