API接口设计规范,看这篇就足以了
优秀的设计是产品变得卓越的原因。设计API意味着提供有效的接口,可以帮助API使用者更好地了解、使用和集成,同时帮助人们有效地维护它。每个产品都需要使用手册,API也不例外。
在API领域,可以将设计视为服务器和客户端之间的协议进行建模。API协议可以帮助内部和外部的利益相关者理解应该做什么,以及如何更好地协同工作来构建一个出色的API。 一、API接口1.什么是API接口
应用程序编程接口(Application Programming Interface,API接口),是应用程序重要的组成部分,就是应用程序对外提供了一个操作数据的入口,这个入口可以是一个函数或类方法,也可以是一个url地址或者一个网络地址。当客户端调用这个入口,应用程序则会执行对应代码操作,给客户端完成相对应的功能。 2.API接口类型
目前市面上大部分公司开发人员使用的接口实现规范主要有:Restful、RPC。
RPC( Remote Procedure Call ) : 翻译成中文:远程过程调用[远程服务调用]. 从字面上理解就是访问/调用远程服务端提供的api接口。这种接口一般以服务或者过程式代码提供。 服务端提供一个唯一的访问入口地址:http://api.xxx.com/ 或 http://www.xx.com/api 客户端请求服务端的时候,所有的操作都理解为动作,一般web开发时,对应的就是HTTP请求的post请求 通过请求体参数,指定要调用的接口名称和接口所需的参数
action=get_all_student&class=301&sex=1m=get_all_student&sex=1&age=22&command=100&sex=1&age=22
接口多了,对应函数名和参数就多了,前端在请求api接口时难找.容易出现重复的接口
Restful: 翻译成中文: 资源状态转换.(表征性状态转移)
把服务端提供的所有的数据/文件都看成资源, 那么通过api接口请求数据的操作,本质上来说就是对资源的操作了.
因此,Restful中要求,我们把当前接口对外提供哪种资源进行操作,就把资源的名称写在url地址。
web开发中操作资源,最常见的最通用的无非就是增删查改,所以restful要求在地址栏中声明要操作的资源是什么。然后通过http请求动词来说明对该资源进行哪一种操作。
POST http://www.xxx.com/api/students/ 添加学生数据
GET http://www.xxx.com/api/students/ 获取所有学生
DELETE http://www.xxx.com/api/students// 删除id=pk的一个学生
PUT http://www.xxx.com/api/students// 修改一个学生的全部信息 [id,name,sex,age,]
PATCH http://www.xxx.com/api/students// 修改一个学生的部分信息[age]
也就是说,我们仅需要通过url地址上的资源名称结合HTTP请求动作,就可以说明当前api接口的功能是什么了。
Restful是以资源为主的api接口规范,体现在地址上就是资源就是以名词表达。
RPC则以动作为主的api接口规范,体现在接口名称上往往附带操作数据的动作。 3.为什么要编写接口文档
为了在团队内部形成共识、防止个人习惯差异引起的混乱,我们都需要找到一种大家都觉得很好的接口实现规范,而且这种规范能够让后端写的接口,用途一目了然,减少客户端和服务端双方之间的合作成本。
由于接口所包含的内容比较细,在项目中常常需要使用接口文档。研发人员可以根据接口文档进行开发、协作,测试人员可以根据接口文档进行测试,系统也需要参照接口文档进行维护等。 二、API接口规范1.协议
API与客户端用户的通信协议,推荐使用HTTPS协议,同时兼容HTTP,以确保交互数据的传输安全。 2.域名
应该尽量将API部署在专用域名之下。
https://api.xxx.com
如果确定API很简单,不会有进一步扩展,可以考虑放在主域名下。
https://www.xxx.com/api/ 3.版本(Versioning)
推荐将API的版本号放入URL。
https://api.xxx.com/app/v1.0/foo
https://api.xxx.com/app/v1.1/foo
https://api.xxx.com/app/v2.0/foo
另一种做法是,将版本号放在HTTP头信息中,但不如放入URL方便和直观。
版本号规范:
1)采用多版本并存,增量发布的方式。
2)版本号可以分为整型和浮点型
整型:大功能版本,如v1、v2、v3 ...
浮点型:补充功能版本,如v1.1、v1.2、v2.1、v2.2 ...
关于版本兼容性,小版本变化向下兼容的,只要大版本不变化。
3)对于一个API或服务,应在生产中最多保留3个最详细的版本 4.路径(Endpoint)
路径又称"终点"(endpoint),表示API的具体网址,每个网址代表一种资源(resource)
接口命名应该是一个动宾结构,由动词+名词组成,采取驼峰式命名规范,例如:
product/v1.0/getProducts 获取产品
order/v1.1/saveOrder 保存订单
接口命名常见通用动词可以参考如下:
动作
前缀
备注
获取
get
get{XXX}
获取
get
get{XXX}List
新增
add
add{XXX}
修改
update
update{XXX}
保存
save
save{XXX}
删除
delete
delete{XXX}
上传
upload
upload{XXX}
发送
send
send{XXX}
5.基本规范5.1 请求参数
公共参数是每个接口都要携带的参数,描述每个接口的基本信息,用于统计或其他用途,放在header或url参数中。
Query
url?后面的参数,存放请求接口的参数数据。
Header
请求头,存放以下公共参数、APP端公共参数等,也可以存放一些特殊加密字段。
Body
Body体,存放请求接口的参数数据。 公共参数:
参数
说明
备注
app_id
唯一标识用户ID
app_id是全局唯一的,每个app_id将对应一个客户
app_key
加密key
app_key用于参数签名使用,可以理解为加密盐值,注意app_key保存到客户端, 不需要作为参数传递 ,需要做一些安全处理,防止泄露。
timestamp
时间戳
时间戳,是客户端调用接口时对应的当前时间戳,时间戳用于防止DoS攻击。当黑客劫持了请求的url去DoS攻击,每次调用接口时接口都会判断服务器当前系统时间和接口中传的的timestamp的差值,如果这个差值超过某个设置的时间(假如5分钟),那么这个请求将被拦截掉,如果在设置的超时时间范围内,是不能阻止DoS攻击的。timestamp机制只能减轻DoS攻击的时间,缩短攻击时间。如果黑客修改了时间戳的值可通过sign签名机制来处理。
request_id
请求ID
用户请求ID,是客户端随机生成的值,要保证全局唯一,可以参考snowflake算法,作为参数传递过来,增加request_id的目的是一方面增加sign签名的多变性,另一方面主要用于防重放攻击,还可以作为全链路跟踪排查问题手段。
sign
签名
一般用于参数签名,防止参数被非法篡改,最常见的是修改金额等重要敏感参数, sign的值一般是将所有非空参数按照升续排序然后+token+app_key+timestamp+request_id拼接在一起,然后使用某种加密算法进行加密,作为接口中的一个参数sign来传递,也可以将sign放到请求头中。接口在网络传输过程中如果被黑客挟持,并修改其中的参数值,然后再继续调用接口,虽然参数的值被修改了,但是因为黑客不知道sign是如何计算出来的,不知道sign都有哪些值构成,不知道以怎样的顺序拼接在一起的,最重要的是不知道签名字符串中的app_key是什么,所以黑客可以篡改参数的值,但没法修改sign的值,当服务器调用接口前会按照sign的规则重新计算出sign的值然后和接口传递的sign参数的值做比较,如果相等表示参数值没有被篡改,如果不等,表示参数被非法篡改了,就不执行接口了。
token
系统调用的唯一凭证 访问令牌access token, 用于接口中, 用于标识接口调用者的身份、凭证,减少用户名和密码的传输次数。一般情况下客户端(接口调用方)需要先向服务器端申请一个接口调用的账号,服务器会给出一个app_id和一个app_key, app_key用于参数签名使用,注意app_key保存到客户端,需要做一些安全处理,防止泄露。
Token的值一般是UUID,服务端生成Token后需要将token做为key,将一些和token关联的信息作为value保存到缓存服务器中(redis),当一个请求过来后,服务器就去缓存服务器中查询这个Token是否存在,存在则调用接口,不存在返回接口错误,一般通过拦截器或者过滤器来实现。
一般token、timestamp、request_id和sign 四个参数会在接口中会同时作为参数传递,每个参数都有各自的用途,其中首次获取token需要app_id、timestamp、request_id、sign,客户端获取token后不再需要传递app_id。APP 端请求公共参数
APP端请求参数除了上述公共参数外,还需要以下额外公共参数:
参数
说明
备注
network
网络
WIFI、4G
operator
运营商
中国联通/移动
platform
平台
iOS、Android
system
系统
ios 13.3、android 9
device
设备型号
iPhone XR、小米9
udid
设备唯一标示
过滤参数:
若记录数量很多,服务器不可能返回全部记录给用户。
API应该提供分页参数及其它筛选参数,过滤返回结果。
参数示例如下
limit=10:指定返回记录的数量
offset=10:指定返回记录的开始位置。
page=2&per_page=100:指定第几页,以及每页的记录数。
sort_by=name&order=asc:指定返回结果按照哪个属性排序,以及排序顺序。 注意:
1)上传/下载
上传/下载,参数增加文件md5,用于完整性校验(传输过程可能丢失数据)。
2)避免精度丢失
缩小单位保存数据,如:钱以分为单位、距离以米为单位。 5.2 响应数据
为了方便给客户端响应,响应数据会包含三个属性,状态码(code),信息描述(message),响应数据(data)。客户端根据状态码及信息描述可快速知道接口,如果状态码返回成功,再开始处理数据。
array类型数据。通过list字段,保证data的Object结构。
返回示例:
{ code: "SUCCESS", // 返回码, 详情后面的【接口返回码】部分会说 data: {} , // 数据 message: "成功" // 存放响应信息提示,显示给客户端用户【须语义化中文提示】 }
分页类型数据。返回总条数,用于判断是否可以加载更多。
返回示例: { code: "SUCCESS", data: { "list":[] "total":10 }, // 数据, message: "成功" }
响应状态码code统一使用英文组合字符串,多层分级使用"."分隔,例如:
PARAMETER.ILLEGALL
PARAMETER.ILLEGALL代表参数错误,不推荐使用数字,数字错误码可读性太差。
注意:
1)返回属性名命名时,建议使用驼峰命名,首字母小写。
2)返回属性值为空时,严格按类型返回默认值。
3)返回金额类型/时间日期类型的属性值,如果仅用来显示,建议后端返回可以显示的字符串。
4)返回业务逻辑的状态码和对应的文案,建议后端两者都返回,中间添加"|"分隔,例如"SUCCESS|成功",SUCCESS表示接口状态成功,显示给客户表示"成功"。
5)调用方不需要的属性,不要返回。 5.3使用GET/POST作为接口请求方式
一般调用接口最常用的两种方式就是GET和POST。两者的区别也很明显,GET请求会将参数暴露在浏览器URL中,而且对长度也有限制。为了更高的安全性,所有接口都采用POST方式请求。
另外不推荐使用rest的PUT和DELETE,因为很多浏览器不支持,很多框架也不支持。
我们这里用的的GET和POST同RESTFul中的GET、POST是不一样的。通常使用GET、POST的选择点在于,简单的用GET、复杂对象用POST,并没有动作的含义,例如我也可以使用get来执行添加的动作,如果参数很多,我也可以使用POST来执行查询操作;但在REST里,GET对应的是查询一个资源,而POST对应的是新增一个资源,意义是决然不同的。理解这一点非常重要。 5.4返回格式
返回响应数据采用JSON,不推荐使用XML,XML是W3C为了替换HTML研发出来的,但是现在很明显失败了。
默认情况下要支持gzip 三、接口安全规范3.1安全设计规范
获取token一般会涉及到几个参数app_id,app_key,timestamp,request_id,sign。我们通过以上几个参数来获取调用系统的凭证。 app_id和app_key可以直接通过平台线上申请,也可以线下直接颁发。app_id是全局唯一的,每个app_id将对应一个客户,app_key需要客户端高度保密。 timestamp是时间戳,使用系统当前的unix时间戳。时间戳的目的就是为了减轻DDOS的攻击。防止请求被拦截后一直尝试请求接口。服务器端设置时间戳阀值,如果请求时间戳和服务器时间超过阀值,则响应失败。 request_id是随机值。随机值主要是为了增加sign的多变性,也可以保护接口的幂等性,相邻的两次请求reqeust_id不允许重复,如果重复则认为是重复提交,响应失败。 sign是参数签名,将所有非空参数按照升续排序、app_key、timestamp、reqeust_id拼接起来进行md5加密(当然使用其他方式进行不可逆加密也没问题)。
token作为系统调用的唯一凭证,token可以设置一次有效,也可以设置时效性,这里推荐设置时效性。如果一次有效的话这个接口的请求频率可能会很高。token推荐加到请求头上,这样可以跟业务参数完全区分开来。
这里面主要涉及到sign签名设计规范和token生成规范,需要遵守如上规范,能够保证API接口的安全性和幂等性。 3.2客户端IP白名单
ip白名单是指将接口的访问权限对部分ip进行开放。这样就能避免其他ip进行访问,设置ip白名单比较麻烦的一点就是当你的客户端进行迁移后,就需要重新联系服务提供者添加新的ip白名单。设置ip白名单的方式很多,除了传统的防火墙之外,spring cloud alibaba提供的组件sentinel也支持白名单设置。为了降低api的复杂度,推荐使用防火墙规则进行白名单设置或者在API网关层面设置IP白名单,比如shenyu网关支持IP白名单设置。 3.3单个接口针对ip限流
限流是为了更好的维护系统稳定性。使用redis进行接口调用次数统计,ip+接口地址作为key,访问次数作为value,每次请求value+1,设置过期时长来限制接口的调用频率。
不过这里还是推荐在网关层面进行设置,比如shenyu网关支持IP限流。 3.4敏感数据加密与脱敏
参数安全:
登录密码、支付密码,需加密后传输,建议使用非对称加密
响应结果:
用户手机号、用户邮箱、身份证号、支付账号、邮寄地址等要进行脱敏,部分数据加 * 号处理。
在接口调用过程中数据通常需要脱敏安全处理,最常用的方式就是加密。加密方式使用安全性比较高的RSA非对称加密。非对称加密算法有两个密钥,这两个密钥完全不同但又完全匹配。只有使用匹配的一对公钥和私钥,才能完成对明文的加密和解密过程。 四、API接口幂等性
幂等性是指任意多次请求的执行结果和一次请求的执行结果所产生的影响相同。说的直白一点就是查询操作无论查询多少次都不会影响数据本身,因此查询操作本身就是幂等的。但是新增操作,每执行一次数据库就会发生变化,所以它是非幂等的。
我们无法保证接口的每一次调用都是有返回结果的,要考虑到出现网络异常的情况。
举个例子,订单创建时,我们需要去减库存,这时接口发生了超时,调用方进行了重试,这时是否会多扣一次库存?
对于一些重要的操作需要防止客户端重复提交的(如非幂等性重要操作),具体办法是当请求第一次提交时将request_id作为key保存到redis,相应的返回结果集作为value存储到redis,并设置超时时间。当同一个请求第二次访问时会先检测redis是否存在该request_id,如果存在则证明重复提交了,接口直接返回不再继续调用了。 五、API调用流程
1.接口调用方(客户端)向接口提供方(服务器)申请接口调用账号,申请成功后,接口提供方会给接口调用方一个app_id和app_key
2.客户端携带参数app_id、timestamp、request_id、sign去调用服务器端的API token,其中sign=加密(app_id + timestamp +request_id+ app_key)
3.使用参数app_id,timestamp,request_id,sign来获取token,token作为系统调用的唯一凭证
4.客户端拿着token 去访问相应的接口
5.如果token过期需要获取刷新token
sign的作用是防止参数被篡改,客户端调用服务端时需要传递sign参数,服务器响应客户端时也可以返回一个sign用于客户端校验返回的值是否被非法篡改了。 六、接口文档
1、尽量采用自动化接口文档,可以做到在线测试,同步更新,推荐使用swagger、yapi。
2、应包含:接口BASE地址、接口版本、接口模块分类等。
3、每个接口应包含:
接口地址:不包含接口BASE地址。
请求方式: GET、POST。
请求参数:数据格式【默认JSON、可选form data】、数据类型、是否必填、中文描述。
响应参数:类型、中文描述。 七、总结
关于限流设计、熔断设计、降级设计,目前主流网关都有相关功能(比如shenyu网关),可以不在API实现中开发这些功能。
另外推荐把API相关日志存储到日志平台,日志平台有利于故障定位和日志统计分析以及接口监控。
日志平台的搭建可以使用的是ELK组件,使用Logstash进行收集日志文件,使用Elasticsearch引擎进行搜索分析,最终在Kibana平台展示出来。
警惕!孩子也会得带状疱疹!得了怎么办?带状疱疹是由水痘带状疱疹病毒引起的。初次感染的水痘带状疱疹病毒,潜伏于感觉神经节中,再激活之后,就表现为沿神经分布的簇集性水疱,我们称之为带状疱疹。中医称之为蛇串疮。因为其好发于腰
新生宝宝反复吐奶,排便带血,竟因肠子在打转!医生争分夺秒抢救新生儿宝宝呕吐溢奶是很常见的一种现象,但近日,厦门市妇幼保健院来了两个呕吐的新生儿宝宝,情况非常紧急,原来他们的肠子在肚子里打转了,经过医师争分夺秒的抢救把肠子解锁,宝宝们终于顺利
那些提前退休的年轻人35岁这一年,因为目前阶段已经没有上升空间了,剩下来的只有压力和焦虑,从事游戏发行工作的饼干离开了大厂,选择提前退休。他发现,生活的幸福感提升了很多,比如,一个微小的细节是,再也不
镇魂街武神觉醒全民比拼玩法一览,击杀鬼王收获巅峰体验!作为一款2D横版格斗动作手游的镇魂街武神觉醒,相信广大游戏爱好者不会感到有陌生感。精致的人物画风华丽的技能特效爽快的多人PK让人眼前一亮,再加上动感的配乐,想想就能为玩家带来动作游
更年期女性应该如何避孕?点击蓝字关注我们更年期女性应该如何避孕?更年期的女性卵巢功能开始下降,月经变得不规律,经量也明显稀少,但仍会有不规则的排卵。只要有成熟的卵泡排出,女性就有怀孕的可能。据世界卫生组织
瑞金病例丨胚胎移植七次失败,如何获得好孕?人们常说,人和人的相遇是缘分,而一个生命和另一个生命的相遇,更是缘分,这里说的相遇,是精子和卵子孕育生命的相遇。这件在很多人看来水到渠成的事情,在刘先生和小苏身上,却是一场颇为艰难
无论如何进化都是火鸡与农场主,一切尽在掌控01什么是Webshell?Webshell就是以aspphpjsp或cgi等网页文件形式存在的一种代码执行环境,一般可以通过浏览器来交互执行,也可以将其称做为一种网页后门。如果攻
顺着脾胃的脾气吃孩子才能真正的健康怎么样做才是对脾胃好呢?关键还是吃好一日三餐黄帝内经中有五谷为养,五果为助,五畜为益,万菜为充的说法,把主食蔬果肉蛋奶合理搭配好,不偏食挑食,这就是顺着脾胃的脾气来吃平时可以适当给
血色清晨新婚夜引发的惨祸,4人丧命背后愚昧无知最害人中华文明历经五千年岁月洗礼积淀了无数文化瑰宝,但是任何事物的发展都不可能是一帆风顺的。在中华文明的演进过程中也伴随着一些糟粕文化的产生,其中不乏毒害人的身心的愚昧思想。血色清晨这部
旅行社业者用心设计才能收获大不同我们发现,3年之后出境团队游恢复,游客更加追求品质,也更加追求体验感了。旅行社需要更加用心地做产品,提升服务质量,才能留住客户。首批出境游团队陆续回国后,旅行社业者不约而同地做了同
一睡成名!女贪官陪睡40多名官员!3月财经新势力从古至今,贪官之所以会贪,实际上都是心中的欲望和贪婪在作祟。当金钱蒙蔽了双眼,权色左右了人心!靠颜值上位,在某些地方的提干过程中,往往颜值比文凭更重要。尤其是女干部更
春季防晒小贴士以下哪个面部器官对紫外线更敏感?蚂蚁庄园答案春天是一个美好的季节,万物复苏,百花盛放,人体的各项机能也会开始活跃。特别是皮肤细胞,在寒冷的冬天会处于相对封闭状态,春天气温回升后就会变得相对开放而敏感。另外,人体适应了冬季紫外
最近火了一种穿搭叫连衣裙裸靴,今年春天这么穿,洋气又显瘦一个人的魅力是不被定义的,我们可以表达出自己想要展现出的风格和魅力,最便捷的渠道无非就是借助穿搭改变。而春夏季节,穿衣搭配的潮流趋势也开始变化,若你不知道穿什么,可以试试今年很火的
时尚的裴寨来源新乡日报派气十足的西装,五彩缤纷的时装,高端大气的羊绒大衣,还有那小可爱的校服套装,分不同款式展示在不同区域。这不是北上广地区的时装展览,实实在在来自一个山村的服装产业园。这里
某荣耀引毒虫仿妆热议,争议官媒差评!胆小勿入!毒虫妆惊魂争议官媒差评是视觉艺术还是娱乐罪恶?胆小勿入!想要五官好看,不是先要有正确的三观吗?韩拍热播剧黑荣耀最近带火了一波某平台的仿妆热度。惨白颓废粉眼圈!寡瘦单薄没精神,成为整
47岁舒淇毁容式近照曝光,满头白发,面容苍老47岁舒淇毁容式近照曝光,满头白发,面容苍老,嫁给冯德伦7年后,她彻底放飞自我了有网友说这个年纪白发很正常,她只是没染而已,染了一样精彩!看看几个月前上热搜的舒淇,曼妙的身姿超棒的
为什么头发眉毛都是直的,私处的毛却是卷的?告诉你答案头条创作挑战赛大家好!我是杨医生,本篇文章关键内容毛发特征,下面为你科普。人体毛发对于大家的作用是很多的,常见的就是保护作用通风散热等,总之对于人体有益。但是不知道大家有没有发现一
难道是我的眼光下降了?就在前几天,美甲的宋姐想要定一款手镯平时宋姐也是一直在店里忙活,生意也是越来越火爆很多客人戴的都有翡翠手镯有的客人看见她老是瞄她的镯子就打趣的说宋姐这么好看的手,也应该配一个好看的
42岁汪小菲现身北京街头!不穿内衬胆子大,走出离婚阴影放飞自我汪小菲北京街头3月22日,知名网络红人汪小菲现身北京街头,一身笔挺的黑色西装非常帅气,搭配上驼色的头层牛皮名牌皮鞋,让他的衣品,一下提高了不少。不过,汪小菲却并没有穿着内衬引起了网
幸福是一种能力幸福是一种能力无论遭遇何种情况,幸福人士都能够在顺境中享受和分享快乐,在逆境中学会与黑暗相处,即使在黑暗之中也能尽锐出奇,散发光芒。其实,幸福的奥秘说白了就是这么简单。让我们一起追
物联网如何打造生态圈?专家提议产业链共创由南京邮电大学广东校友会和南邮校友企业家联盟联合主办物联网大数据与创新创业分享活动近日在高新兴集团总部举行。100多名来自产学研各界的南邮校友,深入探讨物联网前沿技术及行业发展趋势
TMobile将推出富兰克林无线公司新款5G移动热点据Newswire3月21日报道,富兰克林无线公司(FranklinWireless)继续引领宽带数据通信领域的发展,宣布推出最新的5Gsub6移动热点JEXtreamRG2100