一、摘要
2015年左右,移动互联网的兴起,伴随着的是服务端的演进。之前我们还在写MVC下的整站,后来就变成了给前端、客户端提供接口。
因为接口是对外的,既然给别人使用,那总是有一些标准的,我做了简单的归纳,如果你刚开始写接口相关的工作,希望能给你启发。
面向人群:0-3年,初级工程师,不区分语言。
二、接口规范&版本更新
目前常见的有三种,分别是REST、RPC、GraphQL。
- REST,基于资源的调用方式,是关于资源的
- RPC,远程过程调用,是关于动作的
- GraphQL,是查询接口
对于一般的客户端调用服务端实现业务,推荐使用REST,根据实际公司业务,再做微调。
- 完整的REST规范,针对对资源的动作不同,使用GET、PUT、POST、DELETE
- 简化的REST,只保留GET、POST
具体看团队成员情况,判断使用那种风格。
那么,一个基于REST风格的接口地址应该是这样的。
/v1/user/info get 获取信息 post 更新信息
如何设计REST风格的API,关注下面几个问题即可。
- 操作的对象是名词,比如订单、资料
- 通过HTTP方法GET/PUT/POST/DELETE映射对资源的操作
其中的版本管理,建议根据实际使用的框架进行路由配置。
/v1/user/info /v2/user/info
这样做版本定义的好处在于,客户端对于调用接口的版本一目了然,很好管理。
此外,其他可以定义接口版本的方式还有下面几种,都是行得通的,我们可以根据自己的团队沟通进行选择。
- 版本号放在Header中
- 版本号带在URL的参数中,比如
/user/info?ver=2
三、异常处理
我们把错误处理分两个层面看,基于业务的和基于请求的。
首先讲基于请求的访问,比如未经授权的访问,对于修改用户资料的接口,我们需要拿到用户的身份,但是没有走登录的操作就没有对应的身份验证,关于身份验证后面单独讲。
基于请求的访问异常还包括
- 错误的访问路径
- 超出限制访问频率
- 身份验证不通过
- 没有对应操作的授权
以上类似的异常处理,通过HTTP状态码返回即可。客户端拿到HTTP状态码之后,直接进行处理。而接口返回的。
常用的HTTP状态码有
- 200 OK
- 301 永久重定向
- 302 临时重定向
- 304 文档内容没有改变
- 400 参数错误
- 404 对应资源不存在
- 405 请求方法错误
- 413 提交数据过大
- 414 请求URI太长
- 500 服务器内部错误
- 502 网关无响应
- 503 服务器维护或过载
- 504 网关超时
以上的HTTP状态码基本涵盖一般业务中遇到的场景。
然后就是基于业务的异常处理,比如用户名或密码错误。
对于业务类型异常,我们一般放在响应内,例如
{ "code": 0 }
而对于code在项目中对应业务的定义,一般给出接口文档中详细列出。
四、接口文档
早期的接口文档并没有自动化工具,都是手动写文档,上传到工作群文件中的。
后来出现了一些文档平台,具体可以看我之前总结的文章,虽然是几年前的了,现在看还是有参考价值的。
但是,在开发工作之外,额外维护一份文档,对于开发人员来说也是一种负担,我们可以采用代码生成文档的方式解决这个问题。
这里推荐https://swagger.io/ ,此外Java推荐knife4j
。
五、身份验证
身份验证具体指的是登录用户的身份验证,由于接口调用是无状态的,所以我们需要通过传递能校验身份的字符串token
。
一般我们会在请求中把token放在Header里,自定义使用的key,比如x-token
。
对于客户端来说,token不需要自己的去解析,所以只需要存储并传递即可。
一般我们使用的加密方式为jwt,是形如下面的字符串
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
解密后的内部结构为
Header
{ "alg": "HS256", "typ": "JWT" }
Payload
{ "sub": "1234567890", "name": "John Doe", "admin": true }
Signature
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
一般我们将用户的uid放在Payload中。
六、总结
本文从接口规范到身份验证,总体地介绍了如何写接口这一件事,希望能够给大家启发。