如何设计符合RESTful规范的URL?

6 阅读6分钟

设计符合RESTful规范的URL是搭建标准化API的核心第一步——好的URL能让接口语义清晰、易于维护,前端/移动端开发者无需查阅文档就能理解接口用途。

一、RESTful URL的核心原则(必须遵守)

RESTful URL设计的核心是**“URL只标识资源,操作由HTTP方法表达”**,所有设计规则都围绕这一核心展开:

  1. 资源为中心:URL仅描述“要操作的是什么”,而非“要做什么”;
  2. 无动词原则:禁止在URL中包含get/add/delete/update等操作动词;
  3. 语义清晰:通过名词和层级,让URL具备“自解释性”;
  4. 无状态关联:URL不包含会话、状态等临时信息(如token、session_id)。

正反示例对比

场景错误URL(含动词/语义混乱)正确URL(仅标识资源)对应HTTP方法
获取所有用户/api/getAllUsers/api/usersGET
获取单个用户/api/getUser/1/api/users/1GET
创建用户/api/addUser/api/usersPOST
更新用户/api/updateUser/1/api/users/1PUT/PATCH
删除用户/api/deleteUser/1/api/users/1DELETE

二、RESTful URL命名规范(工业级标准)

2.1 资源命名:用名词复数,不用单数

  • 原因:URL标识的是“资源集合”或“集合中的单个资源”,复数名词更符合语义(如/users表示用户集合,/users/1表示集合中的第1个用户);
  • ✅ 正确:/api/users、/api/orders、/api/products;
  • ❌ 错误:/api/user、/api/order、/api/product。

2.2 格式规范:小写+连字符,禁用大写/下划线

  • 原因:URL对大小写敏感(如/users/1和/Users/1是两个URL),小写可避免歧义;连字符(-)比下划线(_)更易读,符合HTTP URL的通用规范;
  • ✅ 正确:/api/user-orders、/api/product-categories;
  • ❌ 错误:/api/userOrders、/api/User_Orders、/api/USER-ORDERS。

2.3 层级规范:最多3层,按“资源/子资源”分层

  • 原则:按“主资源/子资源/子资源实例”分层,层级过多会导致URL臃肿、可读性差;
  • ✅ 正确
    • /api/users(主资源:用户集合);
    • /api/users/1/orders(子资源:用户1的订单集合);
    • /api/users/1/orders/2(子资源实例:用户1的第2个订单);
  • ❌ 错误:/api/users/1/orders/2/products/3(层级超过3层,语义混乱)。

2.4 参数规范:过滤/分页/排序放查询字符串

  • 原则:URL仅标识资源,过滤、分页、排序等条件通过查询字符串(Query String)传递,而非嵌入URL;
  • ✅ 正确
    • /api/users?page=1&size=10(分页:第1页,每页10条);
    • /api/users?status=active&role=admin(过滤:活跃的管理员用户);
    • /api/users?sort=create_time&order=desc(排序:按创建时间降序);
  • ❌ 错误:/api/users/active/admin、/api/users/page/1/size/10。

2.5 版本规范:版本号放URL前缀或请求头

  • 场景:API迭代时需兼容旧版本,版本号建议放在URL前缀(简单直观)或HTTP请求头(更优雅);
  • ✅ 正确
    • URL前缀(推荐):/api/v1/users、/api/v2/users;
    • 请求头(优雅):Accept: application/vnd.api.v1+json(前端在请求头指定版本);
  • ❌ 错误:/api/users/v1、/api/users?version=1(版本号与资源混合)。

三、不同场景的RESTful URL设计示例(全覆盖)

以下是开发中最常见的10类场景,附标准URL设计和语义说明:

3.1 基础资源操作(单资源)

操作场景URLHTTP方法语义说明
获取所有用户/api/v1/usersGET获取用户集合
获取单个用户/api/v1/users/1GET获取ID=1的用户
创建用户/api/v1/usersPOST向用户集合中添加新用户
全量更新用户/api/v1/users/1PUT替换ID=1的用户所有信息(需传全字段)
部分更新用户/api/v1/users/1PATCH仅更新ID=1的用户指定字段
删除用户/api/v1/users/1DELETE删除ID=1的用户

3.2 关联资源操作(主资源+子资源)

操作场景URLHTTP方法语义说明
获取用户1的所有订单/api/v1/users/1/ordersGET获取用户1的订单集合
获取用户1的订单2/api/v1/users/1/orders/2GET获取用户1的ID=2的订单
为用户1创建订单/api/v1/users/1/ordersPOST向用户1的订单集合添加新订单
更新用户1的订单2/api/v1/users/1/orders/2PUT全量更新用户1的订单2
删除用户1的订单2/api/v1/users/1/orders/2DELETE删除用户1的订单2

3.3 过滤/分页/排序操作

操作场景URLHTTP方法语义说明
获取活跃的管理员用户/api/v1/users?status=active&role=adminGET过滤条件:状态=活跃,角色=管理员
获取用户第2页数据/api/v1/users?page=2&size=20GET分页:第2页,每页20条
按创建时间降序排用户/api/v1/users?sort=create_time&order=descGET排序:创建时间降序
组合条件(过滤+分页)/api/v1/users?status=active&page=1&size=10GET活跃用户,第1页,每页10条

3.4 特殊资源操作(非CRUD)

部分场景无法完全用CRUD表达(如用户登录、刷新Token),需兼顾RESTful规范:

操作场景URLHTTP方法语义说明
用户登录(获取Token)/api/v1/auth/loginPOST资源:认证会话,操作:创建会话
刷新Token/api/v1/auth/refresh-tokenPOST资源:Token,操作:刷新
批量删除用户/api/v1/users/batch-deletePOST资源:用户批量操作,操作:删除
导出用户数据/api/v1/users/exportGET资源:用户数据,操作:导出

四、常见错误与避坑指南(新手必看)

4.1 错误1:URL中包含操作动词

  • ❌ 错误:/api/deleteUser/1、/api/getUserOrders/1;
  • ✅ 修正:/api/users/1(DELETE)、/api/users/1/orders(GET);
  • 原因:操作语义应由HTTP方法表达,URL仅标识资源。

4.2 错误2:资源用单数名词

  • ❌ 错误:/api/user/1、/api/order/2;
  • ✅ 修正:/api/users/1、/api/orders/2;
  • 原因:即使是单个资源,也属于“资源集合中的一员”,复数更符合RESTful语义。

4.3 错误3:层级过深或语义混乱

  • ❌ 错误:/api/users/1/orders/2/products/3/comments;
  • ✅ 修正:/api/products/3/comments?order_id=2&user_id=1;
  • 原因:层级超过3层后,URL可读性大幅下降,改用查询参数关联资源更清晰。

4.4 错误4:将参数嵌入URL路径

  • ❌ 错误:/api/users/active/1/page/2;
  • ✅ 修正:/api/users?status=active&is_vip=1&page=2;
  • 原因:过滤/分页参数属于“操作条件”,而非“资源标识”,应放在查询字符串。

4.5 错误5:URL包含动态状态信息

  • ❌ 错误:/api/users?token=xxx、/api/users/session/abc123;
  • ✅ 修正:Token放在HTTP请求头(Authorization: Bearer );
  • 原因:RESTful API要求“无状态”,URL不应包含会话、Token等临时状态信息。