告别混乱接口:RESTful API 规范实战指南

告别混乱接口:RESTful API 规范实战指南 REST 代表的是表现层状态转移REpresentational State TransferREST 本身并没有创造新的技术、组件或服务它只是一种软件架构风格是一组架构约束条件和原则而不是技术框架REST 有一系列规范满足这些规范的 API 均可称为 RESTful API。了解和掌握RESTful API的规范有助于提升程序员的软实力REST 架构对资源的操作包括获取、创建、修改和删除这些操作正好对应 HTTP 协议提供的 GET、POST、PUT 和 DELETE 方法。简单来说RESTful API就是前后端接口对接的规范。RESTful API 设计原则主要用来进行RESTful API 设计原则落地的是两个关键点URI 设计 和 HTTP Method通过URI和HTTP Method 更好的理解Api的作用和功能开发人员在浏览文档、对接接口的时候更加简洁、方便和高效。 话外之音是前后端分离开发的模式下咱俩这样约定好规范 URI 设计资源都是使用 URI 标识的我们应该按照一定的规范来设计URI通过规范化可以使我们的 API 接口更加易读、易用。以下是 URI 设计时应该遵循的一些规范资源名使用名词而不是动词并且用名词复数表示下面的接口都是menus。URI 结尾不应包含/URI 中最好不要出现下划线 ( 我个人觉得下划线不够友好 )URI 路径用小写不要用大写。避免层级过深的 URI超过 2 层的资源嵌套会很乱建议将其他资源转化为传递的参数GET /api/admin/menus?page1PUT /api/admin/menus/1 DELETE /api/admin/menus/2 POST /api/admin/menus GET /api/admin/menus?title权限管理taballcategory_id5HTTP Method 规范基本上 RESTful API 都是使用 HTTP 协议原生的 GET、PUT、POST、DELETE 来标识对资源的 CRUD 操作的在 RESTful API 设计中资源Resource是核心抽象我们通常把资源分为两类Collection 资源集合资源和 Member 资源成员 / 单个资源HTTP 方法Collection 资源Member 资源是否安全是否幂GET/admin/menus 获得整个菜单数据集合/admin/menus/1 集合中的单个实例一般这个后面是ID是是PUT/admin/menus/1 更新数据更新数据中某些属性否否POST/admin/menus 保存数据没有这类操作否是DELETE/admin/menus/2 删除资源删除某个资源否是在这里有几点是我自己总结的和需要注意的地方有些地方更新数据使用PATCH方法但我觉得更新属性使用PUT方法即可没有必要使用PATCH相同资源要统一字段名称GET 返回的结果要尽量可用于 PUT、POST 操作中。POST 方法仅用来创建或者批量删除这两种场景批量删除通常是多条数据传递数组更加安全和保险。删除单条数据统一使用DELETE方法。下面是段使用PHP编写的代码实例这是在路由上区别资源的方法、功能和作用使路由更加简捷、方便。# 角色模块Route::group(roles,staticfunction(){Route::get(,role/roles);Route::post(,role/add);Route::delete(:roleId,role/delete);Route::put(:roleId/menus,role/saveMenus);Route::put(:roleId/status,role/status);Route::put(:roleId,role/update);});# 菜单模块Route::group(menus,staticfunction(){Route::get(,menu/menus);Route::delete(:menuId,menu/delete);Route::post(,menu/add);Route::put(:menuId/status,menu/status);Route::put(:menuId,menu/update);});通过URI方式拼接好的路径在使用上也更加方便代码如下publicfunctionstatus(int$menuId):\think\response\Json{$status$this-request-put(status/d,,trim);if(empty($menuId)||empty($status)){returnshow(config(status.empty.code),config(status.empty.message));}$data[menu_status$status,update_timedate(Y-m-d H:i:s),update_admin_id$this-adminInfo[admin_id],update_admin_name$this-adminInfo[admin_name],];$rbacServicenewRbacService();$rows$rbacService-editMenu($menuId,$data);if($rows){returnshow($this-successCode,$this-successMessage);}else{returnshow($this-errorCode,$this-errorMessage);}}统一返回格式一个规范的 RESTful API 返回格式通常包含状态元数据和业务数据两大部分同时要结合 HTTP 状态码一起使用而非仅靠自定义码。1. 基础通用结构JSON 格式这是业界最常用、最易扩展的统一格式你可以直接参考使用{code:200,// 自定义业务状态码核心message:success,// 可读的状态描述成功/失败原因data:{},// 业务数据成功时返回失败时可为null/{}timestamp:1742195945000,// 请求处理时间戳毫秒便于排查问题requestId:req-8a4501c37657// 请求唯一标识便于链路追踪}2.成功场景单条的直接在data下面多条的在list下面。{code:200,message:操作成功,data:{list:[{role_id:1,role_name:超级管理员},{role_id:2,role_name:运营}],total:3}}这里的业务状态码是根据自己的业务而划定比如1000 开头的都属于用户验证信息相关 2000开头的都属于权限相关的。//用户验证信息相关accountEmpty[code1001,message后台用户账号不能为空,],passwordEmpty[code1002,message后台用户密码不能为空,],//组织架构、权限相关exist[code2001,message角色名称已存在,],优点1. 通用性强易于理解和使用RESTful API 基于 HTTP 协议的原生特性设计比如用GET查询、POST新增、PUT全量更新、DELETE删除等请求方法表达操作语义用 URL 表示资源而非操作。市面上大部分的开发都是前后端分离的模式来开发无论开发语言Java/Python/Go、客户端类型前端 / 移动端 / 第三方系统开发者都能基于 HTTP 常识快速理解和调用 API降低学习成本和沟通成本。2.无状态高可扩展性RESTful API 要求无状态以前的web开发的会话管理大部分依赖Cookie 和 Session后来分布式和微服务发展后无状态的会话管理更有利于业务的需求所以服务器不保存客户端的会话信息每个请求都包含完成该请求所需的全部信息比如通过 JWT 传递身份信息。3.可缓存提升性能RESTful API 充分利用 HTTP 的缓存机制如Cache-Control、ETag响应头客户端可缓存 GET 请求的结果重复请求时直接使用缓存减少网络传输和服务器压力在之前的工作经验中部门内没有规则同学们都是各写各的搞的十分头疼如果是RESTful API 风格统一这样就可以在Nginx添加缓存在Http请求入口出多了一个可以优化性能的点。以下是一个针对 HTTP GET 请求接口启用 20 分钟缓存的 Nginx 配置示例包含了详细的参数说明和功能注释。该配置使用proxy_cache模块对后端动态接口进行缓存仅对GET和HEAD方法生效缓存时长为 20 分钟1200 秒。# 在 http 块中定义缓存路径和相关参数http{# 缓存存放路径及共享内存区域定义proxy_cache_path /var/cache/nginxlevels1:2keys_zonemy_cache:10mmax_size1ginactive60muse_temp_pathoff;# 参数说明# - /var/cache/nginx : 缓存文件存放的本地目录# - levels1:2 : 缓存目录层级减少单目录文件过多# - keys_zonemy_cache:10m : 定义共享内存区域名称my_cache和大小10MB用于存储缓存键和元数据# - max_size1g : 缓存数据最大占用磁盘空间为 1GB# - inactive60m : 如果缓存的数据在 60 分钟内未被访问则自动删除即使未过期# - use_temp_pathoff : 避免将临时文件写入 proxy_temp 目录直接写入缓存目录提升性能server{listen80;server_name www.work.com;# 对需要缓存的 API 接口进行配置例如所有以 /api/ 开头的请求location /api/{# 启用缓存并指定使用上面定义的共享内存区域proxy_cache my_cache;proxy_cache_methods GET HEAD;proxy_cache_key$scheme$host$request_uri;# 针对不同响应码设置缓存有效期proxy_cache_valid20030220m;# 状态码 200 和 302 缓存 20 分钟# 当请求包含特定头或参数时跳过缓存常用于开发/调试# 例如如果请求头中有 X-No-Cache 或者查询字符串包含 nocache则直接透传至后端proxy_cache_bypass$http_x_no_cache$arg_nocache;proxy_no_cache$http_x_no_cache$arg_nocache;# 向客户端发送缓存命中状态响应头中会显示 X-Proxy-Cache: HIT/MISSadd_header X-Proxy-Cache$upstream_cache_status;# 可选设置请求头向后端传递客户端真实 IP 等信息proxy_set_header Host$host;proxy_set_header X-Real-IP$remote_addr;proxy_set_header X-Forwarded-For$proxy_add_x_forwarded_for;# 后端服务地址示例proxy_pass http://backend_server;# 其他代理相关配置如超时、缓冲等proxy_connect_timeout 5s;proxy_read_timeout 10s;proxy_send_timeout 10s;}# 其他 location 配置...}}4.标准化团队协作更高效RESTful 有统一的设计规范如资源用名词、URL 层级表示资源关系、用 HTTP 状态码表示请求结果团队内所有人按同一标准设计 API避免 “一人一个风格”比如有人用/getUser有人用/user/query便于接口文档自动化如 Swagger 可直接基于 RESTful API 生成文档降低团队协作成本。