Laravel API 接口接收字段和响应字段分别进行驼峰转下划线和下划线转驼峰

阅读 (356)
在前后端分离的开发模式下,常会出现一些字段大小写或下划线规则定义的问题,比如前端JS习惯用小驼峰命名字段,后端数据库字段却常常用下划线来定义字段,那在接收时,要么要求前端传来的字段写成下划线命名,要么前端写成小驼峰传递,后端在接收字段时,先将字段预处理成下划,但在接口返回时,又需要照顾前端字段命名规则,需将字段转成小驼峰给前端。 看着挺绕的,其实不管怎么样的规则,只要定义一个中间件来处理即可

在App\Http\Middleware目录中创建一个文件:ApiCaseConverter.php

<?php
namespace App\Http\Middleware;
 
use Closure;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Str;
use Symfony\Component\HttpFoundation\ParameterBag;
 
/**
 * Class ApiCaseConverter
 *
 * 1. 将前端发送来的请求参数的驼峰命名转换为后端的下划线命名
 * 2. 将后端响应参数的下划线命名转换为前端的驼峰命名
 *
 * @package App\Http\Middleware
 */
class ApiCaseConverter  {
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $this->convertRequestNameCase($request);
 
        /** @var Response $response */
        $response = $next($request);
 
        $this->convertResponseNameCase($response);
 
        return $response;
    }
 
    /**
     * 转换请求参数中的下划线命名转换为驼峰命名
     *
     * @param Request $request
     */
    private function convertRequestNameCase($request)
    {
        $this->convertParameterNameCase($request->request);
        $this->convertParameterNameCase($request->query);
        $this->convertParameterNameCase($request->files);
        $this->convertParameterNameCase($request->cookies);
    }
 
    /**
     * 将参数名称的驼峰命名转换为下划线命名
     *
     * @param ParameterBag $parameterBag
     */
    private function convertParameterNameCase($parameterBag)
    {
        $parameters = $parameterBag->all();
        $newParameters = [];
        foreach ($parameters as $key => $value) {
            $newParameters[Str::snake($key)] = $value;
        }
 
        $parameterBag->replace($newParameters);
    }
 
    /**
     * 将响应中的参数命名从下划线命名转换为驼峰命名
     *
     * @param Response $response
     */
    private function convertResponseNameCase($response)
    {
        $content = $response->getContent();
        $json = json_decode($content, true);
        if (is_array($json)) {
            $json = $this->recursiveConvertNameCaseToCamel($json);
            $response->setContent(json_encode($json));
        }
    }
 
    /**
     * 循环迭代将数组键值转换为驼峰格式
     *
     * @param array $arr
     * @return array
     */
    private function recursiveConvertNameCaseToCamel($arr)
    {
        if (!is_array($arr)) {
            return $arr;
        }
 
        $outArr = [];
        foreach ($arr as $key => $value) {
            $outArr[Str::camel($key)] = $this->recursiveConvertNameCaseToCamel($value);
        }
 
        return $outArr;
    }
}

再到 App\Http\Middleware\Kernel.php 中, 找到 $middlewareGroups, 在api中添加中间件即可

protected $middlewareGroups = [
        'web' => [
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
            \Illuminate\Session\Middleware\StartSession::class,
            // \Illuminate\Session\Middleware\AuthenticateSession::class,
            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
            \App\Http\Middleware\VerifyCsrfToken::class,
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],

        'api' => [
            'throttle:api',
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
            \App\Http\Middleware\ApiCaseConverter::class // 这里添加中间件
        ],
];

这样一来,不管前端提交信息时,字段是驼峰还是其他规则,都会在接口接收到数据时,转成下划线规则。

后端返回数据时,字段都会转成小驼峰字段名给前端。这样即可保证前端字段命名的统一,又可以在后端接收数据后,省去了在每个模型中去对字段做预处理

更新于:2021-01-22 14:55:33
返回顶部