laravel9大家是如何构建API接口的

5.X-7.X、8版本的laravel构建API的话一般是Dingo+JWT(tymon/jwt-auth)构建API和认证。但是随着laravel9(今早安装的,已经9.2了)的更新和以前的DingoAPI、JWT已经不维护了,那么大家是如何构建API的?

如何优雅的构建API的统一出口和提示?之前统一在App/Http下的Controller里写successfail方法,因为Http下的控制器都继承App/Http下的Controller;code也是使用HTTP状态码,稍微复杂点的就使用常量或者枚举的方式自定义状态码。

如果进行了代码分层,例如:InterfaceServiceReposetoryController,如何更优雅的处理结果?是在Service调用Reposetory后对结果进行throw呢还是return?

《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
最佳答案

我是封装了一个助手函数,自定义返回状态码使用了枚举,错误代码在 Exceptions/Handler.php 中进行判断,然后返回给助手函数

关于分层调用,我个人更倾向 throw,这样不必判断调用的返回值,我使用的是 abort() 助手函数,和我以下封装的方法契合度很高。

助手函数:

function apiResponse($msg = '', $data = [], $code = 200, $modifyCode = '枚举业务码,比如:0,1,2,-1 这些')
{
    if($code < 400)
    { 
        $res['message'] = $msg;
        $res['data'] = $data ;
        $res['code'] = $modifyCode;
    } else {
        if(app()->enviroment('production'))
        {
            $res['code'] = $code;
            $res['message'] = '系统错误,请稍后重试'; 
        } else {
             // 业务判断
        }
    }
    return response($res, $code);
}

Exceptions/Handler.php

public function render($request, Throwable $e)
    {
        if($request->wantsJson())
        {
            $msg = $e->getMessage();
            $code = 500;
            $errors = [];
            if($e instanceof HttpException)
            {
                $code = 400;
            }
            if($e instanceof ValidationException)
            {
                $code = 422;
                $errors = $e->errors();
                $msg = Status::FAIL_MESSAGES['param'];
            }
            if($e instanceof ModelNotFoundException)
            {
                $msg = Status::FAIL_MESSAGES['incorrect'];
                $code = 404;
            }
            if($e instanceof AuthorizationException)
            {
                $msg = $e->getMessage();
                $code = 419;
            }
            if($e instanceof AuthenticationException)
            {
                $msg = $e->getMessage();
                $code = 403;
            }
            return apiResponse($errors, __($msg), $code);
        }
        return parent::render($request, $e);
    }

自己瞎搞的,也没人指导过我,有不好的地方你可以优化或者指导我一下。

2年前 评论
她来听我的演唱会 (楼主) 2年前
MArtian (作者) 2年前
她来听我的演唱会 (楼主) 2年前
讨论数量: 33

我是封装了一个助手函数,自定义返回状态码使用了枚举,错误代码在 Exceptions/Handler.php 中进行判断,然后返回给助手函数

关于分层调用,我个人更倾向 throw,这样不必判断调用的返回值,我使用的是 abort() 助手函数,和我以下封装的方法契合度很高。

助手函数:

function apiResponse($msg = '', $data = [], $code = 200, $modifyCode = '枚举业务码,比如:0,1,2,-1 这些')
{
    if($code < 400)
    { 
        $res['message'] = $msg;
        $res['data'] = $data ;
        $res['code'] = $modifyCode;
    } else {
        if(app()->enviroment('production'))
        {
            $res['code'] = $code;
            $res['message'] = '系统错误,请稍后重试'; 
        } else {
             // 业务判断
        }
    }
    return response($res, $code);
}

Exceptions/Handler.php

public function render($request, Throwable $e)
    {
        if($request->wantsJson())
        {
            $msg = $e->getMessage();
            $code = 500;
            $errors = [];
            if($e instanceof HttpException)
            {
                $code = 400;
            }
            if($e instanceof ValidationException)
            {
                $code = 422;
                $errors = $e->errors();
                $msg = Status::FAIL_MESSAGES['param'];
            }
            if($e instanceof ModelNotFoundException)
            {
                $msg = Status::FAIL_MESSAGES['incorrect'];
                $code = 404;
            }
            if($e instanceof AuthorizationException)
            {
                $msg = $e->getMessage();
                $code = 419;
            }
            if($e instanceof AuthenticationException)
            {
                $msg = $e->getMessage();
                $code = 403;
            }
            return apiResponse($errors, __($msg), $code);
        }
        return parent::render($request, $e);
    }

自己瞎搞的,也没人指导过我,有不好的地方你可以优化或者指导我一下。

2年前 评论
她来听我的演唱会 (楼主) 2年前
MArtian (作者) 2年前
她来听我的演唱会 (楼主) 2年前

目前使用的就是controller.php里封装的json方法,你要想到处都可以用,放自定义助手函数里也行,全局可用

2年前 评论
她来听我的演唱会 (楼主) 2年前

php-open-source-saver/jwt-auth

2年前 评论
她来听我的演唱会 (楼主) 2年前
goStruct 2年前

我是封装了一个助手函数,自定义返回状态码使用了枚举,错误代码在 Exceptions/Handler.php 中进行判断,然后返回给助手函数

关于分层调用,我个人更倾向 throw,这样不必判断调用的返回值,我使用的是 abort() 助手函数,和我以下封装的方法契合度很高。

助手函数:

function apiResponse($msg = '', $data = [], $code = 200, $modifyCode = '枚举业务码,比如:0,1,2,-1 这些')
{
    if($code < 400)
    { 
        $res['message'] = $msg;
        $res['data'] = $data ;
        $res['code'] = $modifyCode;
    } else {
        if(app()->enviroment('production'))
        {
            $res['code'] = $code;
            $res['message'] = '系统错误,请稍后重试'; 
        } else {
             // 业务判断
        }
    }
    return response($res, $code);
}

Exceptions/Handler.php

public function render($request, Throwable $e)
    {
        if($request->wantsJson())
        {
            $msg = $e->getMessage();
            $code = 500;
            $errors = [];
            if($e instanceof HttpException)
            {
                $code = 400;
            }
            if($e instanceof ValidationException)
            {
                $code = 422;
                $errors = $e->errors();
                $msg = Status::FAIL_MESSAGES['param'];
            }
            if($e instanceof ModelNotFoundException)
            {
                $msg = Status::FAIL_MESSAGES['incorrect'];
                $code = 404;
            }
            if($e instanceof AuthorizationException)
            {
                $msg = $e->getMessage();
                $code = 419;
            }
            if($e instanceof AuthenticationException)
            {
                $msg = $e->getMessage();
                $code = 403;
            }
            return apiResponse($errors, __($msg), $code);
        }
        return parent::render($request, $e);
    }

自己瞎搞的,也没人指导过我,有不好的地方你可以优化或者指导我一下。

2年前 评论
她来听我的演唱会 (楼主) 2年前
MArtian (作者) 2年前
她来听我的演唱会 (楼主) 2年前

一般的业务返回我是封装了 一个成功和失败


    protected function successResponse($data, $msg = 'success'): JsonResponse
    {
        return Response()->json([
            'code' => 1,
            'msg'  => $msg,
            'data' => $data,
        ],Response::HTTP_OK);
    }

    protected function failR($msg):JsonResponse
    {
        return $this->failResponse([],$msg);
    }

    protected function failResponse($data, $msg = 'fail'): JsonResponse
    {
        return Response()->json([
            'code' => 0,
            'msg'  => $msg,
            'data' => $data
        ],Response::HTTP_OK);
    }
2年前 评论
她来听我的演唱会 (楼主) 2年前

如果返回是 json 直接 return 数组就可以了,没必要 return response()->json()

2年前 评论
IceBay 2年前
她来听我的演唱会 (楼主) 2年前

在app/helpers目录下创建ApiResponse统一返回,创建ResponseEnum HTTP请求错误码集合,然后在基类控制器中use就可以使用了。这个是我创建的一个laravel基础项目,你可以借鉴一下,有问题也可以交流一下。 gitee.com/wangfor/laravel8

2年前 评论
她来听我的演唱会 (楼主) 2年前

自带的Sanctum基本可以代替tymon/jwt-auth了,还是官方的香

2年前 评论

能用官方的就用官方的,之前项目里边有两个数据库,用dingo api很多坑

2年前 评论
pndx

没有人用中间件统一处理返回的吗?

2年前 评论
她来听我的演唱会 (楼主) 2年前
pndx (作者) 2年前

使用自带的 http status code + msg 即可,不用封装什么统一返回,脱了裤子放屁,Laravel 本身自带的状态码返回就是统一的

2年前 评论
陈先生

前几天写了个demo,你可以参考一下,具体的话可以自定义 摸鱼大全之错误信息的响应

至于你说之前在Controller 里面定于的 SuccessFail,我觉得可以抽出来做成 Trait.

2年前 评论
if (!function_exists("success")) {
    /**
     * 成功返回
     * @param  mixed  $data
     * @param  int  $code
     * @param  string  $message
     * @param  array  $headers
     * @param  int  $options
     * @return \Illuminate\Http\JsonResponse
     */
    function success(mixed $data = [], int $code = 200, string $message = "Success", array $headers = [], int $options = 0): \Illuminate\Http\JsonResponse
    {
        return response()
            ->json(
                array_merge(
                    [
                        'code' => 1
                    ], compact(['message', 'data'])
                ),
                $code,
                $headers,
                $options
            );
    }
}
if (!function_exists("fail")) {
    /**
     * 失败返回
     * @param  string  $message
     * @param  int  $code
     * @param  mixed   $data
     * @param  array  $headers
     * @param  int  $options
     * @return \Illuminate\Http\JsonResponse
     */
    function fail(string $message = "Fail", int $code = 400, mixed  $data = [], array $headers = [], int $options = 0): \Illuminate\Http\JsonResponse
    {
        return response()
            ->json(
                array_merge(
                    [
                        'code' => 0
                    ], array_filter(compact(['message', 'data']), function ($item) {
                        return filled($item);
                    })
                ),
                $code,
                $headers,
                $options
            );
    }
}
2年前 评论

我不喜欢在controller里面调用自带方法,我之前写api的习惯是采用Response的宏来生成一个固定格式的response对象

//json response返回
Response::macro('custom', function ($data, int $errcode = 0, string $message = 'success') {
    return response()->json(compact('errcode', 'message', 'data'));
});
//简单分页返回定制
Response::macro('export', function (Builder $query) {
     $count = $query->count();
     $rows = $query->forPage(
     request('page', ConstDefinition::PAGE),
     request('pagesize', ConstDefinition::PAGESIZE)
)->get()->toArray();
            /** @noinspection PhpParamsInspection */
    return new static([
        'data'=>[
            'rows'=>$rows,
            'total'=>$count,
        ],
        'errcode'=>0,
         'msg'=>'查询成功',
    ]);
});
2年前 评论

一个功能一个文件夹,一个包 返回 return $this->error() return $this->success() 格式随你定

2年前 评论

不管是throw还是return最好都使用HttpExceptionInterface这个接口。return的用一个自定义函数把需要响应的数据封装一下。如果是service的话就是return,如果是common的话就是抛出。

2年前 评论
laravel_peng
2年前 评论
pndx 2年前

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