REST(Representational State Transfer,表述性状态转移)是一种软件架构风格,由Roy Fielding在2000年的博士论文中提出。RESTful API就是遵循REST架构风格设计的API。
REST的核心思想是:把所有东西都看作资源(Resource),每个资源有一个唯一的URI(统一资源标识符),通过HTTP方法(GET、POST、PUT、DELETE等)对资源进行操作,用HTTP状态码表示操作结果,资源的表述格式通常是JSON或XML。
RESTful API因为简单、规范、易于理解和扩展,已经成为目前最流行的API设计风格,几乎所有的互联网公司都在用。
但很多人设计的API并不真正RESTful,只是"看起来像"RESTful——URL里用动词、所有请求都用GET或POST、状态码永远返回200、参数命名混乱、没有版本控制。这样的API不规范,难用,也难维护。
今天分享RESTful API设计的最佳实践,帮你设计出规范、易用、易维护的API。
URL设计
URL是API的入口,设计好URL是第一步。
第一,用名词,不用动词:URL应该表示资源,用名词,不用动词。比如获取用户列表,应该是GET /users,而不是GET /getUsers;创建用户,应该是POST /users,而不是POST /createUser。HTTP方法已经表示了动作(GET=获取,POST=创建,PUT=更新,DELETE=删除),URL里不需要再用动词。
第二,用复数名词:资源集合用复数名词,如/users、/articles、/orders。单个资源用/资源集合/id,如/users/123、/articles/456。
第三,层级关系:如果资源之间有从属关系,用层级URL表示。比如某篇文章的评论,是/articles/123/comments;某个用户的订单,是/users/456/orders。层级不要太深,一般不超过两层。
第四,用连字符,不用下划线:多单词的URL用连字符(-)分隔,不用下划线(),因为连字符在URL里更易读,也符合SEO规范。比如/user-profiles,而不是/userprofiles。
第五,全小写:URL全部小写,因为URL是大小写敏感的(虽然有些服务器不区分),全小写避免混淆。
好的URL示例:
- GET /users — 获取用户列表
- GET /users/123 — 获取id为123的用户
- POST /users — 创建用户
- PUT /users/123 — 更新id为123的用户
- DELETE /users/123 — 删除id为123的用户
- GET /users/123/articles — 获取用户123的文章列表
- GET /articles/456/comments — 获取文章456的评论列表
HTTP方法
RESTful API用HTTP方法表示对资源的操作:
- GET:获取资源(查询),安全且幂等
- POST:创建资源,不安全且不幂等
- PUT:更新资源(全量更新),不安全但幂等
- PATCH:更新资源(部分更新),不安全,不保证幂等
- DELETE:删除资源,不安全但幂等
- HEAD:获取资源的元信息(和GET一样,但不返回body)
- OPTIONS:获取资源支持的方法
幂等(Idempotent)的意思是,多次执行同一个请求,结果是一样的。比如GET /users/123,调用一次和调用一百次,返回的结果是一样的(假设数据没变)。DELETE /users/123,调用一次删除了,再调用返回404,结果也是一致的(资源不存在了)。POST不幂等,因为调用两次会创建两个资源。
PUT和PATCH的区别:PUT是全量更新,需要传完整的资源数据;PATCH是部分更新,只传需要修改的字段。比如更新用户的邮箱,PUT要传用户的所有字段,PATCH只传email字段。
HTTP状态码
RESTful API用HTTP状态码表示操作结果,不要所有请求都返回200然后在body里写错误码。
常用状态码:
- 200 OK:请求成功(GET/PUT/PATCH成功)
- 201 Created:资源创建成功(POST成功)
- 204 No Content:请求成功,但没有返回内容(DELETE成功)
- 301 Moved Permanently:永久重定向
- 304 Not Modified:资源未修改(用缓存)
- 400 Bad Request:请求参数错误
- 401 Unauthorized:未认证(需要登录)
- 403 Forbidden:已认证,但无权限
- 404 Not Found:资源不存在
- 405 Method Not Allowed:方法不允许
- 409 Conflict:资源冲突(如重复创建)
- 422 Unprocessable Entity:请求格式正确,但语义错误(如验证失败)
- 429 Too Many Requests:请求过于频繁(限流)
- 500 Internal Server Error:服务器内部错误
- 502 Bad Gateway:网关错误
- 503 Service Unavailable:服务不可用
- 504 Gateway Timeout:网关超时
正确使用状态码,能让API更规范,客户端可以根据状态码做不同的处理。
版本控制
API会不断迭代,版本控制很重要。有几种版本控制方式:
- URL路径:/v1/users、/v2/users(最常用,最直观)
- 查询参数:/users?version=1
- 请求头:Accept: application/vnd.myapp.v1+json
推荐用URL路径的方式,最简单直观,也方便调试。版本号用整数(v1、v2),不用小数(v1.1),因为API版本是不兼容的升级才加版本号。
认证和授权
API通常需要认证,常用的认证方式:
- API Key:在请求头或参数里传API Key,简单但安全性一般,适合开放API
- OAuth 2.0:行业标准的授权框架,适合第三方应用授权
- JWT(JSON Web Token):无状态的token认证,适合前后端分离的应用
- Session/Cookie:传统的会话认证,适合同域应用
认证信息放在请求头里(如Authorization: Bearer token),不要放在URL参数里(会被日志记录)。
分页、排序、过滤
列表接口通常需要分页、排序、过滤功能。
分页:用page和pagesize参数,如GET /users?page=2&pagesize=20。返回结果里包含总数(total)、当前页(page)、每页数量(pagesize)、总页数(totalpages)。
排序:用sort参数,如GET /articles?sort=-createdat(负号表示降序),或sort=createdat,desc。
过滤:用查询参数过滤,如GET /articles?category=tech&status=published&author_id=123。
错误处理
错误响应应该包含错误码、错误信息、错误详情,方便客户端排查问题。
错误响应格式示例:
{
"error": {
"code": "VALIDATION_ERROR",
"message": "请求参数验证失败",
"details": [
{
"field": "email",
"message": "邮箱格式不正确"
}
]
}
}错误码用字符串(如USERNOTFOUND),比数字更易读。错误信息用人类可读的描述。details字段可以包含详细的错误列表(如表单验证的每个字段错误)。
API文档
API文档很重要,没有文档的API就是灾难。好的API文档应该包含:接口说明、URL、HTTP方法、请求参数、响应示例、错误码、认证方式。
常用的API文档工具:
- Swagger/OpenAPI:行业标准,自动生成交互式文档
- API Blueprint:用Markdown写API文档
- RAML:RESTful API建模语言
- Postman:可以生成API文档和Mock
推荐用Swagger/OpenAPI,它是行业标准,工具生态丰富,可以自动生成文档、客户端SDK、Mock服务器。
其他最佳实践
第一,用JSON格式,不用XML。JSON更轻量、更易读、更流行。响应头设置Content-Type: application/json。
第二,字段命名用snakecase(下划线)或camelCase(驼峰),保持一致。推荐用snakecase,和数据库字段一致,也更易读。
第三,时间用ISO 8601格式(如2015-04-29T21:00:00+08:00),不用时间戳(虽然时间戳也可以,但ISO格式更易读)。
第四,开启CORS(跨域资源共享),如果API需要被不同域名的前端调用。
第五,限流(Rate Limiting),防止恶意请求和滥用。在响应头里返回X-RateLimit-Limit、X-RateLimit-Remaining、X-RateLimit-Reset。
第六,监控和日志,记录API的调用情况、响应时间、错误率,及时发现和解决问题。
第七,向后兼容,API更新时尽量保持向后兼容,不要随意删除字段或修改字段含义。不兼容的变更要升级版本号。
总结
RESTful API设计看起来简单,但要设计得规范、易用、易维护,需要注意很多细节。核心原则是:把一切看作资源,用HTTP方法操作资源,用状态码表示结果,URL用名词不用动词,做好版本控制、认证、分页、错误处理和文档。
好的API能让开发者用得舒心,也能让系统更易维护。希望这些最佳实践能帮你设计出更好的API。
评论(0)
暂无评论,快来抢沙发~
评论功能仅对会员开放,请先登录
登录