Laravelapi 自定义 response 格式

 http路由

laravel的http路由文件有两个api.phpweb.php

➜  ~ ll /Users/shiwenyuan/test/test_demo/routes
total 32
drwxr-xr-x   6 shiwenyuan  staff  192 10  9 12:19 ./
drwxr-xr-x  26 shiwenyuan  staff  832 10  9 10:29 ../
-rw-r--r--   1 shiwenyuan  staff  572 10  9 12:19 api.php
-rw-r--r--   1 shiwenyuan  staff  508 10  9 10:28 channels.php
-rw-r--r--   1 shiwenyuan  staff  553 10  9 10:28 console.php
-rw-r--r--   1 shiwenyuan  staff  453 10  9 10:35 web.php
从命名上不难理解`web.php`为web服务的路由(用到了视图层),`api.php`则是做api服务(只负责返回数据)

 传统写法

直接在app/Http/Controllers/Controller.php中添加实现,然后因为所有控制器都集成了Controller,所以就会有他的所有public方法,但是这么写个人感觉不够优雅,与laravel的核心思想背道而驰,所以我就把相关实现放到了Provider

 创建response服务供应者

php artisan make:provider ResponseMacroServiceProvider

//该命令会在app/Providers目录下生成ResponseMacroServiceProvider
<?php
namespace App\Providers;

use Illuminate\Support\ServiceProvider;
class ResponseMacroServiceProvider extends ServiceProvider
{
    /**
     * Register services.
     *
     * @return void
     */
    public function register()
    {
        //
    }

    /**
     * Bootstrap services.
     *
     * @return void
     */
    public function boot()
    {
        //
    }
}
//初始文件格式如上

 修改实现

<?php
namespace App\Providers;

use Carbon\Carbon;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Response;
use App\Library\Error;

class ResponseMacroServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap services.
     *
     * @return void
     */
    public function boot()
    {
        //error
        Response::macro('fail', function ($err_code, $result=null, $msg='') {
            if (is_null($result)){
                $result = [];
            }
            if ($msg) {
                $err_msg = $msg;
            } else {
                $err_msg = Error::errMsg($err_code);
            }
            $response_data = [
                'code' => $err_code,
                'message' => $err_msg,
                'timestamp' => Carbon::now()->timestamp
            ];
            app('log')->error(sprintf('params [%s] response [%s]',
                json_encode(request()->all(), JSON_UNESCAPED_UNICODE),
                json_encode($response_data, JSON_UNESCAPED_UNICODE)
            ));
            return Response::json($response_data);
        });

        //正常返回
        Response::macro('success', function ($result=null) {
            if (is_null($result)){
                $result = [];
            }
            $response_data = [
                'code' => 100,
                'content' => $result,
                'timestamp' => Carbon::now()->timestamp
            ];

            app('log')->debug(sprintf('params [%s] response [%s]',
                json_encode(request()->all(), JSON_UNESCAPED_UNICODE),
                json_encode($response_data, JSON_UNESCAPED_UNICODE)
            ));
            return Response::json($response_data);
        });
    }
}

 App\Library\Error的实现

<?php
/**
 * Created by PhpStorm.
 * User: shiwenyuan
 * Date: 2019/10/9 13341007105@163.com
 * Time: 15:13
 */
namespace App\Library;

class Error
{
    public static function errMsg($code)
    {
        $maps = static::getErrs();
        return isset($maps[$code]) ? $maps[$code] : '未知错误';
    }

    public static function getErrs()
    {
        return [
            '500' => '服务器错误',
        ];
    }
}

 在全局服务提供者map中加入自己写的响应服务提供者

文件位置config/app.php

 测试

 增加测试路由

文件路径:routes/api.php

Route::get('test_success', 'IndexController@testSuccess');
Route::get('test_fail', 'IndexController@testFail');

 增加测试实现

<?php

namespace App\Http\Controllers;

class IndexController extends Controller
{
    public function testSuccess()
    {
        return response()->success(['username'=>'shiwenyuan']);
    }

    public function testFail()
    {
        return response()->fail(500);
    }
}

 最终结果

 success

 fail

 日志记录

➜  ~ cat /Users/shiwenyuan/test/test_demo/storage/logs/laravel-2019-10-09.log
[2019-10-09 07:39:02] local.DEBUG: params [{"query":"index"}] response [{"code":100,"content":{"username":"shiwenyuan"},"timestamp":1570606742}]  
[2019-10-09 07:39:05] local.ERROR: params [{"query":"index"}] response [{"code":500,"message":"服务器错误","timestamp":1570606745}]  

原文出处 https://shiwenyuan.github.io/post/ck1irc5v...

本作品采用《CC 协议》,转载必须注明作者和本文链接
原创不易,转载请注明出处
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 6
AloneUtopia

很好。 不过我还是选择写在控制器基类中 :joy:

4年前 评论

@Jinrenjie 嘿嘿,谢谢肯定

4年前 评论

@AloneUtopia 这个还是看个人的喜好

4年前 评论
AloneUtopia

@北行 是的, 主要是我懒。。

4年前 评论

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