
很多人第一次写接口时,会把重点放在“能不能返回数据”。只要前端能调通,页面能显示,就觉得接口设计完成了。
但接口不是临时函数。它是前端、后端、数据库、权限、错误处理和未来扩展之间的契约。一开始设计得太随意,后面每次改功能都会变成连锁反应。
第一个接口不需要复杂,但一定要清楚、稳定、可理解。
写接口前,不要先想 URL,而要先想用户动作。
用户是在创建项目、获取列表、更新设置、上传文件、提交订单,还是查看结果?接口应该服务一个明确动作,不要把多个不相关的动作塞进同一个接口。
比如“创建项目”和“修改项目设置”应该是两个接口;“获取项目列表”和“获取项目详情”也应该分开。
接口越清楚,前端越容易使用,后端越容易维护,问题也越容易排查。
常见的新手写法是:
/api/createProject
/api/getProjectList
/api/updateProject
/api/deleteProject
这种写法能用,但长期会变乱。更推荐用资源路径加 HTTP 方法表达动作:
GET /api/projects
POST /api/projects
GET /api/projects/:id
PATCH /api/projects/:id
DELETE /api/projects/:id
路径表示资源,方法表示动作。这样接口结构更统一,也更容易被别人理解。
接口请求参数通常有三类:路径参数、查询参数和请求体。
路径参数用于定位资源,比如 /api/projects/123 里的 123。查询参数用于筛选、搜索、排序和分页,比如 ?status=active&page=1。请求体用于提交创建或更新的数据。
不要把所有参数都塞进请求体,也不要把复杂数据塞进 URL。
一个清晰的规则是:定位资源放路径,控制列表放查询,提交数据放请求体。
接口返回给前端的数据结构要尽量稳定。不要今天返回数组,明天返回对象;成功时一个结构,失败时另一个完全不相关的结构。
一个常见的成功响应可以是:
{
"data": {
"id": "project_123",
"name": "Demo Project",
"status": "active"
}
}
列表响应可以包含分页信息:
{
"data": [
{ "id": "project_123", "name": "Demo Project" }
],
"pagination": {
"page": 1,
"pageSize": 20,
"total": 128
}
}
稳定的响应结构,会让前端少写很多特殊判断。
接口失败时,不要只返回“失败”或“服务器错误”。
错误响应至少要包含错误码、可读信息和必要的字段信息。比如:
{
"error": {
"code": "PROJECT_NAME_REQUIRED",
"message": "Project name is required.",
"field": "name"
}
}
前端可以根据 code 做逻辑判断,根据 message 展示提示,根据 field 高亮表单字段。
好的错误设计,不只是为了开发者,也是为了用户体验。
不要相信前端传来的任何数据。
即使前端已经限制了字段长度、格式和必填项,后端仍然必须重新校验。因为接口可以被绕过,用户也可以直接请求 API。
校验至少包括:必填字段、字段类型、长度限制、枚举值、数字范围、文件大小、权限范围、业务规则。
输入校验越早越清楚,后面的数据污染越少。
鉴权回答“你是谁”,权限回答“你能不能做这件事”。
很多新手只判断用户是否登录,却忘了判断用户是否有权限操作某个资源。
比如用户登录了,不代表他能删除别人的项目;团队成员能查看项目,不代表他能修改账单;普通用户能上传文件,不代表他能访问管理员接口。
每个涉及用户数据的接口,都要同时考虑鉴权和权限。
幂等性指同一个请求执行多次,结果不会产生意外副作用。
比如用户点击“保存设置”两次,不应该生成两份设置;支付回调收到两次,不应该创建两张订单;删除同一个资源多次,不应该导致系统异常。
不是所有接口都天然幂等,但重要接口要提前设计。
尤其是支付、订单、Webhook、后台任务、批量操作,一定要考虑重复请求。
不要让列表接口一次返回所有数据。
早期数据少时看不出问题,后面数据一多,接口会变慢,页面会卡,数据库压力会变大。
列表接口应该从一开始支持分页、排序和必要筛选。即使当前只有几条数据,也要保留结构。
比如:
GET /api/projects?page=1&pageSize=20&status=active&sort=createdAt_desc
这会让未来扩展更自然。
很多人第一次写 API 就开始设计 /api/v1、/api/v2、复杂版本策略。
如果你的 API 只服务自己的前端,早期不一定需要复杂版本管理。更重要的是保持响应结构稳定,避免随意破坏字段含义。
如果你的 API 会开放给第三方,或者会被多个客户端长期使用,就需要更认真地设计版本、兼容策略和弃用流程。
版本号不是越早越专业,而是要看使用边界。
接口文档不需要一开始很华丽,但必须能说明:接口做什么,请求参数是什么,响应是什么,错误有哪些,权限要求是什么。
最简单的文档也可以是:
POST /api/projects
作用:创建项目
权限:登录用户
请求体:name, description
成功:返回项目详情
错误:PROJECT_NAME_REQUIRED, PROJECT_LIMIT_EXCEEDED
文档的价值不是形式,而是减少沟通成本。半年后你自己也会感谢当时写清楚了。
你可以用下面模板设计接口:
接口名称:
用户动作:
资源对象:
HTTP 方法:
路径:
路径参数:
查询参数:
请求体:
权限要求:
成功响应:
错误响应:
是否需要幂等:
是否需要分页:
是否需要日志:
每次写接口前先填这张表,能避免很多随手设计。
第一个接口的目标不是炫技,而是建立稳定的契约。
路径清楚、参数清楚、响应稳定、错误可读、权限明确、文档同步,这些基础做好,后面的功能才会越写越顺。
下一篇,我们继续聊接口和外部系统:Webhook 实战。