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

REST 代表的是表现层状态转移(REpresentational State Transfer),REST 本身并没有创造新的技术、组件或服务,它只是一种软件架构风格,是一组架构约束条件和原则,而不是技术框架,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 层的资源嵌套会很乱,建议将其他资源转化为传递的参数
bash 复制代码
GET /api/admin/menus?page=1
PUT /api/admin/menus/1  
DELETE /api/admin/menus/2
POST /api/admin/menus
GET /api/admin/menus?title=权限管理&tab=all&category_id=5

HTTP 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编写的代码实例,这是在路由上区别资源的方法、功能和作用,使路由更加简捷、方便。

php 复制代码
# 角色模块
Route::group('roles', static function () {
    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', static function () {
    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方式拼接好的路径在使用上也更加方便,代码如下:

php 复制代码
public function status(int $menuId): \think\response\Json
{
    $status = $this->request->put('status/d','','trim');
    if(empty($menuId) || empty($status)){
        return show(config('status.empty.code'),config('status.empty.message'));
    }
    
    $data = [
        'menu_status' => $status,
        'update_time' => date('Y-m-d H:i:s'),
        'update_admin_id' => $this->adminInfo['admin_id'],
        'update_admin_name' => $this->adminInfo['admin_name'],
    ];
    $rbacService = new RbacService();
    $rows = $rbacService->editMenu($menuId,$data);
    if($rows) {
        return show($this->successCode,$this->successMessage);
    }else{
        return show($this->errorCode,$this->errorMessage);
    }
}

统一返回格式

一个规范的 RESTful API 返回格式,通常包含 状态元数据业务数据 两大部分,同时要结合 HTTP 状态码一起使用(而非仅靠自定义码)。

1. 基础通用结构(JSON 格式)

这是业界最常用、最易扩展的统一格式,你可以直接参考使用:

php 复制代码
{
  "code": 200,          // 自定义业务状态码(核心)
  "message": "success", // 可读的状态描述(成功/失败原因)
  "data": {},           // 业务数据(成功时返回,失败时可为null/{})
  "timestamp": 1742195945000, // 请求处理时间戳(毫秒),便于排查问题
  "requestId": "req-8a4501c37657" // 请求唯一标识,便于链路追踪
}

2.成功场景,单条的直接在data下面,多条的在list下面。

php 复制代码
{
    "code": 200,
    "message": "操作成功",
    "data": {
        "list": [
            {
                "role_id": 1,
                "role_name": "超级管理员"
            },
            {
                "role_id": 2,
                "role_name": "运营"
            }
        ],
        "total": 3
    }
}

这里的业务状态码是根据自己的业务而划定,比如1000 开头的都属于用户验证信息相关 ,2000开头的都属于权限相关的。

php 复制代码
//用户验证信息相关
'accountEmpty' => [
    'code' => 1001,
    'message' => '后台用户账号不能为空',
],
'passwordEmpty' => [
    'code' => 1002,
    'message' => '后台用户密码不能为空',
],
//组织架构、权限相关
'exist' => [
    'code' => 2001,
    '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-ControlETag响应头):客户端可缓存 GET 请求的结果,重复请求时直接使用缓存,减少网络传输和服务器压力,在之前的工作经验中部门内没有规则,同学们都是各写各的,搞的十分头疼,如果是RESTful API 风格统一,这样就可以在Nginx添加缓存,在Http请求入口出多了一个可以优化性能的点。

以下是一个针对 HTTP GET 请求接口启用 20 分钟缓存的 Nginx 配置示例,包含了详细的参数说明和功能注释。该配置使用 proxy_cache 模块对后端动态接口进行缓存,仅对 GETHEAD 方法生效,缓存时长为 20 分钟(1200 秒)。

bash 复制代码
# 在 http 块中定义缓存路径和相关参数
http {
    # 缓存存放路径及共享内存区域定义
    proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=1g inactive=60m use_temp_path=off;
    # 参数说明:
    # - /var/cache/nginx          : 缓存文件存放的本地目录
    # - levels=1:2                : 缓存目录层级(减少单目录文件过多)
    # - keys_zone=my_cache:10m    : 定义共享内存区域名称(my_cache)和大小(10MB),用于存储缓存键和元数据
    # - max_size=1g               : 缓存数据最大占用磁盘空间为 1GB
    # - inactive=60m              : 如果缓存的数据在 60 分钟内未被访问,则自动删除(即使未过期)
    # - use_temp_path=off         : 避免将临时文件写入 proxy_temp 目录,直接写入缓存目录,提升性能

    server {
        listen 80;
        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_valid 200 302 20m;   # 状态码 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/MISS)
            add_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 生成文档),降低团队协作成本。
相关推荐
uzong2 小时前
Dubbo 版本升级 3.0.10 升级到 3.1.11 ,3.0.10升级到3.2.16 (过程素材、仅供参考)
后端
dovens2 小时前
Spring Boot(快速上手)
java·spring boot·后端
元Y亨H2 小时前
深入理解基于角色的访问控制(RBAC)
后端
木易士心3 小时前
从 MVP 到千万级并发:AI 在前后端开发中的差异化落地指南
前端·后端
哈基咪怎么可能是AI3 小时前
😱【OpenClaw 源码解析 第3期】你的 AI 助手每次都「失忆」?学会这一招,让它记住你所有重要决策,效率直接翻倍!
人工智能·后端
小杍随笔3 小时前
【Rust 语言编程知识与应用:自定义数据类型详解】
开发语言·后端·rust
波波0073 小时前
每日一题:.NET 中的“表达式树是什么?
后端·.net
饕餮争锋3 小时前
Baas(后端即服务)简介
后端
少卿3 小时前
OpenClaw 的 summarize 技能——开发者的智能摘要利器
前端·后端·程序员