RESTful API设计指南:HTTP方法、状态码与URI规范详解
RESTful API设计指南:HTTP方法、状态码与URI规范详解
RESTful API设计是现代Web开发中非常重要的一部分,它基于HTTP协议,通过统一的接口对资源进行操作,实现客户端与服务器的解耦。本文将详细介绍RESTful的基本概念、设计原则、HTTP方法的使用场景、状态码的含义以及URI设计规范等内容。
什么是RESTful
RESTful(Representational State Transfer)是一种基于HTTP协议设计网络应用程序接口(API)的架构风格,由Roy Fielding在2000年的博士论文中提出。其核心思想是以资源为中心,通过统一的接口对资源进行操作,实现客户端与服务器的解耦。简单来说,RESTful是基于HTTP定义了一组接口格式规范,用来规范所有HTTP请求。
RESTful 设计原则
核心原则
资源导向(Resource-Based)
所有事物抽象为资源(如用户、订单、文章),每个资源有唯一的标识符(URI,如 /users/123)。
资源通过JSON与客户端交互。
统一接口(Uniform Interface)
定义了HTTP方法明确操作类型:
GET:获取资源
POST:创建资源
PUT:更新资源(全量替换)
PATCH:更新资源(部分修改)
DELETE:删除资源
HTTP状态码标识结果
如200 OK、404 Not Found等。
无状态(Stateless)
每个请求必须包含所有必要信息,服务器不保存客户端状态(如Session),提升扩展性和可靠性。
可缓存(Cacheable)
响应需明确是否可缓存(如通过Cache-Control头),减少重复请求
客户端无需关注服务器架构细节(如负载均衡、代理层)
URI命名
使用名词复数表示资源(如/users而非/getUser)。
避免动词,用HTTP方法表达操作(如DELETE /users/123)。
层级关系用/分隔(如/users/123/orders)。
URI中体现版本:/api/v1/users
RESTful 接口类型
GET
- 用途:获取资源(查询数据)。
- 特性:
- 安全:不会修改服务器资源。
- 幂等:多次请求结果相同。
- 可缓存:响应可被浏览器或代理缓存。
- 响应状态码:
- 200 OK(成功)
- 404 Not Found(资源不存在)
- 304 Not Modified(缓存未更新)
GET /users/123 # 获取ID为123的用户信息
GET /users?role=admin # 过滤角色为admin的用户
POST
- 用途:创建新资源(或提交非幂等操作)。
- 特性:
- 非安全:会修改服务器资源。
- 非幂等:多次调用可能产生不同结果(如重复提交订单)。
- 响应状态码:
- 201 Created(成功创建,响应头包含 Location: /users/456)
- 400 Bad Request(请求数据不合法)
- 409 Conflict(资源冲突,如重复创建)
POST /users
Body: { "name": "Alice", "age": 30 } # 创建新用户
PUT
- 用途:全量更新资源(替换整个资源)。
- 特性:
- 幂等:多次调用结果一致(如重复更新同一数据,最终状态相同)。
- 若资源不存在,可创建(需由服务端决定是否支持)。
- 响应状态码:
- 200 OK 或 204 No Content(更新成功)
- 201 Created(资源被创建)
- 404 Not Found(资源不存在且服务端不支持创建)
PUT /users/123
Body: { "name": "Bob", "age": 25 } # 替换用户123的所有字段
DELETE
- 用途:删除资源。
- 特性:
- 幂等:删除后再次调用无效果。
- 响应状态码:
- 204 No Content(删除成功,无返回内容)
- 404 Not Found(资源不存在)
- 403 Forbidden(无权删除)
DELETE /users/123 # 删除ID为123的用户
PATCH
- 用途:部分更新资源(仅修改指定字段)。
- 特性:
- 非幂等:连续相同请求可能导致不同结果(如递增计数器)。
- 需明确传递修改的字段。
- 响应状态码:
- 200 OK 或 204 No Content
- 400 Bad Request(修改格式错误)
- 404 Not Found
PATCH /users/123
Body: { "age": 26 } # 仅更新用户123的年龄
RESTful 状态码
1xx(信息响应)
- 100 Continue
- 客户端应继续发送请求的剩余部分(用于大文件上传前的确认)。
2xx(成功)
- 200 OK
- 请求成功,返回响应数据(如 GET 或 PUT 请求成功)。
- 201 Created
- 资源创建成功(如 POST 请求后返回新资源的URI,响应头包含 Location: /users/123)。
- 202 Accepted
- 请求已接受但未处理完成(常用于异步任务)。
- 204 No Content
- 请求成功,但无返回内容(如 DELETE 成功或 PUT 更新后无需返回数据)。
3xx(重定向)
- 301 Moved Permanently
- 资源永久迁移到新URI(需更新书签)。
- 302 Found
- 资源临时重定向到新URI(浏览器默认行为是后续请求仍用原URI)。
- 304 Not Modified
- 资源未修改,客户端可使用缓存(配合 If-Modified-Since 头使用)。
4xx(客户端错误)
- 400 Bad Request
- 请求格式错误(如参数缺失或JSON语法错误)。
- 401 Unauthorized
- 未认证(需提供有效身份凭证,如JWT失效)。
- 403 Forbidden
- 已认证但无权限访问资源(如普通用户访问管理员接口)。
- 404 Not Found
- 资源不存在(URI无效或资源已删除)。
- 405 Method Not Allowed
- HTTP方法不支持(如对只允许 GET 的URI发送 POST)。
- 409 Conflict
- 资源状态冲突(如重复创建同名用户)。
- 429 Too Many Requests
- 请求频率超出限制(常见于API限流)。
5xx(服务器错误)
- 500 Internal Server Error
- 服务器内部错误(通用兜底错误,需排查日志)。
- 502 Bad Gateway
- 网关或代理服务器收到无效响应(如后端服务崩溃)。
- 503 Service Unavailable
- 服务暂时不可用(如维护或过载,可配合 Retry-After 头提示重试时间)。
- 504 Gateway Timeout
- 网关或代理服务器超时(后端服务未及时响应)。
RESTful Uri设计原则
对于API的URI命名要遵守以下设计:
- 使用名词复数表示资源(如/users而非/getUser)。
- 避免动词,用HTTP方法表达操作
- 如DELETE /users/123,而不是DELETE /delete-users/123)。
- 层级关系用/分隔
- 如/users/123/orders, 而不是 /users/orders/123
- URI中体现版本:/api/v1/users
- 推荐使用小驼峰,比如/pet/petId
- URI应该大小写敏感,并且推荐使用全小写
- 以上只是建议,具体根据实际情况而定
Example:https://petstore.swagger.io/
- 以下API来自swagger官方例子,可以看到其实并没有严格遵守规范,比如API里没有版本信息,命名里有动词等等
Api传参:QueryString 和 UriPath
使用 URI Path(路径参数)的场景
URI Path 用于标识 资源的主键 或 资源间的层级关系,通常对应服务端的 核心数据模型。
适用场景:
- 唯一资源标识
- 通过路径参数直接定位唯一资源(如用户ID、订单ID)。
GET /users/{id} # 获取指定ID的用户
DELETE /orders/{orderId} # 删除指定ID的订单
- 资源层级关系
- 表示资源之间的从属关系(如用户的所有订单)。
示例:
GET /users/{userId}/orders # 获取用户的订单列表
特点:
- 必要性:路径参数通常是 必填 的(缺少会导致404)。
- 语义明确:路径体现资源的唯一性和结构(如 /users/123 明确指向用户123)。
- 缓存友好:路径参数不同的 URL 会被视为不同资源,适合缓存(如 CDN 缓存)
使用 Query String(查询参数)的场景
Query String 用于 过滤、排序、分页 或 附加操作,通常是 可选 的非核心参数。
适用场景:
- 过滤数据
- 筛选符合特定条件的资源列表。
示例:
GET /users?role=admin&status=active # 获取角色为admin且状态为活跃的用户
- 分页与排序
- 控制返回数据的范围和顺序。
示例:
GET /articles?page=2&limit=20&sort=-created_at # 获取第二页文章,按创建时间倒序
- 附加操作
- 触发特定功能(如统计、导出格式)。
示例:
GET /reports/sales?format=csv # 导出CSV格式的销售报表
GET /products?fields=name,price # 仅返回名称和价格字段(字段选择)
- 非资源标识参数
- 不影响资源定位,仅修饰响应结果。
示例:
GET /search?q=restful&lang=en # 搜索关键词"restful",语言为英文
特点:
- 可选性:缺少查询参数时,通常返回默认结果(如不分页)。
- 灵活性:参数组合自由,适合动态需求(如多种过滤条件)。
- 幂等性:同一 Query String 的 GET 请求是幂等的(结果可缓存)
RESTful和HTTP的区别
- RESTful并不等于HTTP,它只是基于HTTP的一些特性设定了一组设计规范
- 类似的还有GraphQL,也是基于HTTP的特性设定了一组规范
注意事项
- 以上只是标准的设计规范,并没有技术上的限制,开发者完全可以POST当PUT用,PUT当POST用,甚至POST当GET用等等,只是这样不规范,会导致程序可维护性降低
- 现实开发中需要根据实际情况调整,最好和以前的开发风格保持一致
- 大部分API的设计都没有严格的遵守以上规则,比如API的URI里没有版本信息,返回的状态码用的不准确等,使用动词等等