当前位置: 首页 > news >正文

Laravel 开发Api规范

一,修改时区

配置 config/app.php 文件

// 时区修改,感觉两者皆可,自己根据实际情况定义
'timezone' => 'PRC', // 大陆时间

二,设置 Accept 头中间件

accept头即为客户端请求头,做成中间件来使用。Accept 决定了响应返回的格式,设置为 application/json, 遇到的所有报错 Laravel 会默认处理为 JSON 格式。

  1. 生成中间件
php artisan make:middleware AcceptHeader
<?php
namespace App\Http\Middleware;
use Closure;
class AcceptHeader
{public function handle($request, Closure $next){$request->headers->set('Accept', 'application/json');return $next($request);}
}
  1. 添加到全局中间件
    修改文件 app/http/Kernel.php
protected $middlewareGroups = ['web' => [...],'api' => [\App\Http\Middleware\AcceptHeader::class,...],
];

二,统一封装响应码

Enum 枚举,新建app/Enums/ResponseEnum.php

<?phpnamespace App\Enums;class ResponseEnum
{// sevming/laravel-response 默认以 '|' 作为分割错误码与错误信息的字符串public const INVALID_REQUEST = '无效请求|21001';// 001 ~ 099 表示系统状态;100 ~ 199 表示授权业务;200 ~ 299 表示用户业务/*-------------------------------------------------------------------------------------------*/// 100开头的表示 信息提示,这类状态表示临时的响应// 100 - 继续// 101 - 切换协议/*-------------------------------------------------------------------------------------------*/// 200表示服务器成功地接受了客户端请求const HTTP_OK = [200001, '操作成功'];const HTTP_ERROR = [200002, '操作失败'];const HTTP_ACTION_COUNT_ERROR = [200302, '操作频繁'];const USER_SERVICE_LOGIN_SUCCESS = [200200, '登录成功'];const USER_SERVICE_LOGIN_ERROR = [200201, '登录失败'];const USER_SERVICE_LOGOUT_SUCCESS = [200202, '退出登录成功'];const USER_SERVICE_LOGOUT_ERROR = [200203, '退出登录失败'];const USER_SERVICE_REGISTER_SUCCESS = [200104, '注册成功'];const USER_SERVICE_REGISTER_ERROR = [200105, '注册失败'];const USER_ACCOUNT_REGISTERED = [23001, '账号已注册'];/*-------------------------------------------------------------------------------------------*/// 300开头的表示服务器重定向,指向的别的地方,客户端浏览器必须采取更多操作来实现请求// 302 - 对象已移动。// 304 - 未修改。// 307 - 临时重定向。/*-------------------------------------------------------------------------------------------*/// 400开头的表示客户端错误请求错误,请求不到数据,或者找不到等等// 400 - 错误的请求const CLIENT_NOT_FOUND_HTTP_ERROR = [400001, '请求失败'];const CLIENT_PARAMETER_ERROR = [400200, '参数错误'];const CLIENT_CREATED_ERROR = [400201, '数据已存在'];const CLIENT_DELETED_ERROR = [400202, '数据不存在'];// 401 - 访问被拒绝const CLIENT_HTTP_UNAUTHORIZED = [401001, '授权失败,请先登录'];const CLIENT_HTTP_UNAUTHORIZED_EXPIRED = [401200, '账号信息已过期,请重新登录'];const CLIENT_HTTP_UNAUTHORIZED_BLACKLISTED = [401201, '账号在其他设备登录,请重新登录'];// 403 - 禁止访问// 404 - 没有找到文件或目录const CLIENT_NOT_FOUND_ERROR = [404001, '没有找到该页面'];// 405 - 用来访问本页面的 HTTP 谓词不被允许(方法不被允许)const CLIENT_METHOD_HTTP_TYPE_ERROR = [405001, 'HTTP请求类型错误'];// 406 - 客户端浏览器不接受所请求页面的 MIME 类型// 407 - 要求进行代理身份验证// 412 - 前提条件失败// 413 – 请求实体太大// 414 - 请求 URI 太长// 415 – 不支持的媒体类型// 416 – 所请求的范围无法满足// 417 – 执行失败// 423 – 锁定的错误/*-------------------------------------------------------------------------------------------*/// 500开头的表示服务器错误,服务器因为代码,或者什么原因终止运行// 服务端操作错误码:500 ~ 599 开头,后拼接 3 位// 500 - 内部服务器错误const SYSTEM_ERROR = [500001, '服务器错误'];const SYSTEM_UNAVAILABLE = [500002, '服务器正在维护,暂不可用'];const SYSTEM_CACHE_CONFIG_ERROR = [500003, '缓存配置错误'];const SYSTEM_CACHE_MISSED_ERROR = [500004, '缓存未命中'];const SYSTEM_CONFIG_ERROR = [500005, '系统配置错误'];// 业务操作错误码(外部服务或内部服务调用)const SERVICE_REGISTER_ERROR = [500101, '注册失败'];const SERVICE_LOGIN_ERROR = [500102, '登录失败'];const SERVICE_LOGIN_ACCOUNT_ERROR = [500103, '账号或密码错误'];const SERVICE_USER_INTEGRAL_ERROR = [500200, '积分不足'];//501 - 页眉值指定了未实现的配置//502 - Web 服务器用作网关或代理服务器时收到了无效响应//503 - 服务不可用。这个错误代码为 IIS 6.0 所专用//504 - 网关超时//505 - HTTP 版本不受支持/*-------------------------------------------------------------------------------------------*/
}

三,封装 API 返回的统一消息(ApiResponse)

在 app/Helpers 目录下创建 ApiResponse.php 文件

<?phpnamespace App\Helpers;use App\Enum\ResponseEnum;
use App\Exceptions\BaseException;
use Illuminate\Http\JsonResponse;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection;trait ApiResponse
{/*** 成功* @param null $data* @param array $codeResponse* @return JsonResponse*/public function success($data = null, $codeResponse = ResponseEnum::HTTP_OK): JsonResponse{return $this->jsonResponse('success', $codeResponse, $data);}/*** 失败* @param array $codeResponse* @param null $data* @param null $error* @return JsonResponse*/public function fail($codeResponse = ResponseEnum::HTTP_ERROR, $data = null): JsonResponse{return $this->jsonResponse('fail', $codeResponse, $data);}/*** json响应* @param $status* @param $codeResponse* @param $data* @param $error* @return JsonResponse*/private function jsonResponse($status, $codeResponse, $data): JsonResponse{list($code, $message) = $codeResponse;return response()->json(['status' => $status,'code' => $code,'message' => $message,'data' => $data ?? null,]);}/*** 成功分页返回* @param $page* @return JsonResponse*/protected function successPaginate($page): JsonResponse{return $this->success($this->paginate($page));}private function paginate($page){if ($page instanceof LengthAwarePaginator) {return ['total' => $page->total(),'page' => $page->currentPage(),'limit' => $page->perPage(),'pages' => $page->lastPage(),'list' => $page->items()];}if ($page instanceof Collection) {$page = $page->toArray();}if (!is_array($page)) {return $page;}$total = count($page);return ['total' => $total, //数据总数'page' => 1, // 当前页码'limit' => $total, // 每页的数据条数'pages' => 1, // 最后一页的页码'list' => $page // 数据];}/*** 业务异常返回* @param array $codeResponse* @param string $info* @throws BaseException*/public function throwBaseException(array $codeResponse = ResponseEnum::HTTP_ERROR, string $info = ''){throw new BaseException($codeResponse, $info);}
}

四,创建项目异常捕获 Exception 文件

异常分为两种,一种是要给前端返回展示的,比如表单验证,一种是不需要给前端展示的,比如服务器内部错误。

  1. 在 app/Exceptions 目录下创建 BaseException.php 文件用于服务器内部异常的抛出
<?phpnamespace App\Exceptions;use Exception;
class BaseException extends Exception
{/*** 基础异常构造函数* @param array $codeResponse 状态码* @param string $info 自定义返回信息,不为空时会替换掉codeResponse 里面的message文字信息*/public function __construct(array $codeResponse, $info = ''){[$code, $message] = $codeResponse;parent::__construct($info ?: $message, $code);}
}
  1. 自定义返回异常
    修改 app/Exceptions 目录下的 Handler.php 文件
<?phpnamespace App\Exceptions;use App\Enum\ResponseEnum;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Validation\ValidationException;
use Throwable;
use App\Helpers\ApiResponse;
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;class Handler extends ExceptionHandler
{use ApiResponse;/*** A list of exception types with their corresponding custom log levels.** @var array<class-string<\Throwable>, \Psr\Log\LogLevel::*>*/protected $levels = [//];/*** A list of the exception types that are not reported.** @var array<int, class-string<\Throwable>>*/protected $dontReport = [//];/*** A list of the inputs that are never flashed to the session on validation exceptions.** @var array<int, string>*/protected $dontFlash = ['current_password','password','password_confirmation',];/*** Register the exception handling callbacks for the application.** @return void*/public function register(){$this->reportable(function (Throwable $e) {//});}public function render($request, Throwable $exception){   //判断只接管api部分的异常if ($request->is('api/*')) {// 请求类型错误异常抛出if ($exception instanceof MethodNotAllowedHttpException) {$this->throwBaseException(ResponseEnum::CLIENT_METHOD_HTTP_TYPE_ERROR);} // 参数校验错误异常抛出elseif ($exception instanceof ValidationException) {$this->throwBaseException(ResponseEnum::CLIENT_PARAMETER_ERROR, $exception->getMessage());} // 路由不存在异常抛出elseif ($exception instanceof NotFoundHttpException) {$this->throwBaseException(ResponseEnum::CLIENT_NOT_FOUND_ERROR);} // 自定义错误异常抛出elseif ($exception instanceof BaseException) {return response()->json(['status' => 'fail','code' => $exception->getCode(),'message' => $exception->getMessage(),'data' => null,]);//系统异常} else {//生产模式if (config('app.debug')) {return response()->json(['status' => 'fail','code' => 500,'message' => "服务器内部错误!",'data' => null,]);} else {return response()->json(['status' => 'fail','code' => 500,'message' => $exception->getMessage(),'data' => null]);}}}return parent::render($request, $exception);}
}

五,使用

路由定义如下

Route::prefix('v1')->name('api.v1.')->group(function() {Route::get('version', function() {return 'this is version v1';})->name('version');//限速,每分钟只能请求10次Route::get('test', [TestController::class,'test'])->middleware(['throttle:10,1']);Route::post('login', [TestController::class,'login']);Route::post('register', [TestController::class,'register']);Route::group(['middleware' => 'auth.jwt'], function () {Route::get('user', [TestController::class,'user']);Route::get('logout', [TestController::class,'logout']);Route::get('refresh', [TestController::class,'refresh']);});
});

相关文章:

Laravel 开发Api规范

一&#xff0c;修改时区 配置 config/app.php 文件 // 时区修改&#xff0c;感觉两者皆可&#xff0c;自己根据实际情况定义 timezone > PRC, // 大陆时间二&#xff0c;设置 Accept 头中间件 accept头即为客户端请求头&#xff0c;做成中间件来使用。Accept 决定了响应返…...

蓝色wordpress外贸建站模板

蓝色wordpress外贸建站模板 https://www.mymoban.com/wordpress/7.html...

windos环境,使用docker容器运行项目的,新增外部访问地址配置

对于运行在 Docker 容器中的项目&#xff0c;你需要在容器内部编辑 resolv.conf 文件。以下是一种常见的方法&#xff1a; 进入正在运行的 Docker 容器&#xff1a;docker exec -it [container_id] bash其中 [container_id] 是你正在运行的 Docker 容器的 ID。 在容器内部使…...

设计模式:生活中的组合模式

想象一下&#xff0c;你正在组织一个大型的家庭聚会。在这个聚会中&#xff0c;你需要准备各种菜肴&#xff0c;每个菜肴又包含不同的食材。你的目标是能够以统一的方式处理整个聚会的准备工作&#xff0c;不论是处理单个食材还是一整道菜肴。 在这个场景中&#xff0c;我们可…...

WPF OnStartup

在Windows Presentation Foundation (WPF)框架中&#xff0c;OnStartup 是 System.Windows.Application 类的一个受保护的虚方法&#xff0c;它是应用程序启动过程中的一个重要环节。当一个 WPF 应用程序启动时&#xff0c;其入口点通常是 App.xaml 文件和对应的后台代码文件 A…...

docker-相关

打镜像 1、编写dockfile文件&#xff0c;请自行百度 2、docker build -t 镜像名称:版本号 dockerFile路径 3、docker save -o 镜像压缩包名称.tar 镜像名称:镜像版本号 部署镜像 1、将镜像tar包放到部署机器上 2、加载镜像&#xff1a;docker load -i 镜像tar包路径 3、dock…...

二十、Rust AOP 切面增强

用过 java spring 的同学&#xff0c;应该会对 AspectJ 的 前置、后置、环绕 增强 念念不忘&#xff0c;巧了 rust 也有类似能力&#xff0c;稍显不同的是&#xff0c;为了向 “零成本抽象” 靠齐&#xff0c;Rust 的 “增强” 是在编译期 完成的。 编译期生成&#xff0c;则离…...

掌握Go语言:Go语言精细错误,清晰、高效的错误处理实践(32)

错误处理是任何编程语言中都至关重要的一部分&#xff0c;Go 语言提供了一套简单而强大的错误处理机制&#xff0c;使得处理错误变得高效而清晰。 Go 错误类型 在 Go 中&#xff0c;错误是一个普通的接口类型&#xff0c;即 error 接口&#xff0c;其定义如下&#xff1a; t…...

Spring与Web环境的集成

1. ApplicationContext应用上下文获取方式 应用上下文对象是通过new ClasspathXmlApplicationContext(spring配置文件) 方式获取的&#xff0c;但是每次从容器中获得Bean时都要编写new ClasspathXmlApplicationContext(spring配置文件) &#xff0c;这样的弊端是配置文件加载多…...

二叉树的遍历——bfs广度优先搜索

1、BinNode类的创建 &#xff08;1&#xff09;代码总览 ##&#xff08;2&#xff09;测试示例 2、二叉树的遍历 &#xff08;1&#xff09;图示 &#xff08;2&#xff09;代码总览 &#xff08;3&#xff09;测试示例...

飞鸟写作可靠吗 #职场发展#经验分享#经验分享

飞鸟写作是一个非常便捷的论文写作工具&#xff0c;不仅可以帮助用户高效地完成论文写作&#xff0c;还可以提供查重降重的功能&#xff0c;帮助用户确保论文的原创性。那么&#xff0c;飞鸟写作到底可靠吗&#xff1f;答案是肯定的。 首先&#xff0c;飞鸟写作提供的查重降重功…...

Java 实现自定义注解

一、interface 关键字 我们想定义一个自己的注解 需要使用 interface 关键字来定义。 如定义一个叫 MyAnnotation 的注解&#xff1a; public interface MyAnnotation { } 二、元注解 光加上 interface 关键字 还不够&#xff0c;我们还需要了解5大元注解 RetentionTargetDo…...

代码随想录Day48

Day 48 动态规划part09 今日任务 198.打家劫舍213.打家劫舍II337.打家劫舍III 代码实现 基础打家劫舍 class Solution {public static int rob(int[] nums) {if (nums null || nums.length 0) return 0;if (nums.length 1) return nums[0];int[] dp new int[nums.leng…...

Web 后台项目,权限如何定义、设置、使用:菜单权限、按钮权限 ts element-ui-Plus

Web 后台项目&#xff0c;权限如何定义、设置、使用&#xff1a;菜单权限、按钮权限 ts element-ui-Plus 做一个后台管理项目&#xff0c;里面需要用到权限管理。这里说一下权限定义的大概&#xff0c;代码不多&#xff0c;主要讲原理和如何实现它。 一、权限管理的原理 权限…...

ADB 操作命令及其详细用法

adb devices 用途&#xff1a;列出连接到计算机的所有 Android 设备。详解&#xff1a;执行该命令后&#xff0c;ADB 将扫描连接到计算机的所有 Android 设备&#xff0c;并列出它们的序列号。 adb connect <device> 用途&#xff1a;连接到指定 IP 地址的 Android 设备。…...

类的函数成员(三):拷贝构造函数

一.什么是拷贝构造函数&#xff1f; 1.1 概念 同一个类的对象在内存中有完全相同的结构&#xff0c;如果作为一个整体进行复制或称拷贝是完全可行的。这个拷贝过程只需要拷贝数据成员&#xff0c;而函数成员是共用的&#xff08;只有一份拷贝&#xff09;。 在建立对象…...

C#操作MySQL从入门到精通(8)——对查询数据进行高级过滤

前言 我们在查询数据库中数据的时候,有时候需要剔除一些我们不想要的数据,这时候就需要对数据进行过滤,比如学生信息中,我只需要年龄等于18的,同时又要家乡地址是安徽的,类似这种操作专栏第7篇的C#操作MySQL从入门到精通(7)——对查询数据进行简单过滤简单过滤方法就无法…...

Centos 7 安装通过yum安装google浏览器

在CentOS 7上使用yum安装Google Chrome浏览器稍微复杂一些&#xff0c;因为Chrome并不直接包含在默认的Yum仓库中。按照以下步骤来操作&#xff1a; 1、添加Google Chrome仓库 首先&#xff0c;您需要手动添加Google Chrome的Yum仓库。打开终端&#xff0c;并使用文本编辑器&a…...

题目:学习使用按位与 。

题目&#xff1a;学习使用按位与 & 。   There is no nutrition in the blog content. After reading it, you will not only suffer from malnutrition, but also impotence. The blog content is all parallel goods. Those who are worried about being cheated shoul…...

逐步分解,一文教会你如何用 jenkins+docker 实现主从模式

jenkins 主从模式想必大家都不陌生&#xff0c;大家在学习过程中为了学习方便都在自己本地搭建了 jenkins 环境&#xff0c;然后通过 javaweb 方式实现&#xff0c;对于 docker 下实现主从模式大家好像兴趣挺大。 今天就通过这篇文章给大家讲讲怎么玩&#xff0c;希望对大家有…...

React 第五十五节 Router 中 useAsyncError的使用详解

前言 useAsyncError 是 React Router v6.4 引入的一个钩子&#xff0c;用于处理异步操作&#xff08;如数据加载&#xff09;中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误&#xff1a;捕获在 loader 或 action 中发生的异步错误替…...

Linux 文件类型,目录与路径,文件与目录管理

文件类型 后面的字符表示文件类型标志 普通文件&#xff1a;-&#xff08;纯文本文件&#xff0c;二进制文件&#xff0c;数据格式文件&#xff09; 如文本文件、图片、程序文件等。 目录文件&#xff1a;d&#xff08;directory&#xff09; 用来存放其他文件或子目录。 设备…...

从WWDC看苹果产品发展的规律

WWDC 是苹果公司一年一度面向全球开发者的盛会&#xff0c;其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具&#xff0c;对过去十年 WWDC 主题演讲内容进行了系统化分析&#xff0c;形成了这份…...

React Native在HarmonyOS 5.0阅读类应用开发中的实践

一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强&#xff0c;React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 &#xff08;1&#xff09;使用React Native…...

最新SpringBoot+SpringCloud+Nacos微服务框架分享

文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的&#xff0c;根据Excel列的需求预估的工时直接打骨折&#xff0c;不要问我为什么&#xff0c;主要…...

【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】

1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件&#xff08;System Property Definition File&#xff09;&#xff0c;用于声明和管理 Bluetooth 模块相…...

Neo4j 集群管理:原理、技术与最佳实践深度解析

Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...

2025季度云服务器排行榜

在全球云服务器市场&#xff0c;各厂商的排名和地位并非一成不变&#xff0c;而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势&#xff0c;对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析&#xff1a; 一、全球“三巨头”…...

浪潮交换机配置track检测实现高速公路收费网络主备切换NQA

浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求&#xff0c;本次涉及的主要是收费汇聚交换机的配置&#xff0c;浪潮网络设备在高速项目很少&#xff0c;通…...

JavaScript基础-API 和 Web API

在学习JavaScript的过程中&#xff0c;理解API&#xff08;应用程序接口&#xff09;和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能&#xff0c;使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...