导读:在前后端项目开发中,接口设计不仅是连接前后端的桥梁,更是保证系统稳定性、安全性和可维护性的关键环节。设计一个高效、规范且安全的接口,对于开发者而言至关重要。本文将深入剖析接口设计的全流程,从后端开发流程到接口设计规范,再到接口的安全处理,全方位、无死角地解读接口设计的奥秘。
一、接口设计规范
要想设计出一个优秀的接口,我们首要的任务是进行详尽的需求分析。只有深刻理解了业务需求,我们才能全面地规划接口设计,包括接口的基本定义、安全性考量以及幂等性处理等多个方面。
💡需求分析
在接到开发任务后,关键是快速掌握相关模块和业务,依赖原型文档和PRD文档。若缺少原型图,与产品经理紧密沟通至关重要,尤其在需求变更时,通过深入沟通确保全面理解新要求。
下图是后端人员的开发流程,大家要熟悉接口设计处于开发的什么阶段。
接口设计之前的关键点:
- 通读当前业务的PRD文档
- 通读当前业务的原型文档
- 不断的频繁的与产品沟通,直到搞清楚业务为止
- 后期与前端联调的重要依据
💡接口四要素
接口设计是后端开发中的关键环节,规范的接口设计可以提高系统的可维护性和可扩展性。接口设计应包含以下四大要素:
- 请求路径:以模块名称进行区分(英文),通俗易懂。
- 请求方式:符合RESTful风格,查询使用GET,新增使用POST,修改使用PUT,删除使用DELETE。
- 接口入参:包括路径参数、问号传参和请求体参数。路径参数使用
@PathVariable
注解接收,问号传参使用后端形参接收或类中的属性,请求体参数使用JSON对象,后端使用DTO(@RequestBody
)接收。 - 接口出参:统一格式
{code:200,msg:"成功",data:{}}
,数据封装为VO,过滤敏感数据,整合数据。
一个例子
-
接口地址:
/nursing_project
-
请求方式:
GET
-
请求参数:
参数名称 参数说明 数据类型 name 护理项目名称 string status 状态(0:禁用,1:启用) int pageNum 当前页码 int pageSize 每页显示条数 int -
响应示例
{ "code": 200, "msg": "操作成功", "data": { "total": "19", "pageSize": 10, "pages": "2", "page": 1, "records": [ { "id": "1", "createTime": "2023-09-26 15:08:59", "updateTime": "2023-10-28 01:59:27", "createBy": "1671403256519078153", "creator": "行政专员", "name": "翻身拍背", "orderNo": 1, "unit": "次", "price": 30.00, "image": "https://yjy-slwl-oss.oss-cn-hangzhou.aliyuncs.com/424a475d-76b1-4c57-b430-60293901ef79.jpg", "nursingRequirement": "帮助患者翻身,并进行背部按摩,以促进血液循环", "status": 0, "count": 2 } ] }, "operationTime": null }
💡接口测试
接口编写完毕后,需要使用接口工具进行测试。常见的接口测试工具有:
- Postman
- Apifox
- Swagger 在线接口文档
- Knife4j(Swagger的增强版,可生成离线接口文档)
使用这些工具测试接口时,需要知道明确的接口信息。
二、接口的安全
💡参数校验
入参出参校验是每个程序员必备的基本素养。你设计的接口,必须先校验参数。比如入参是否允许为空、入参长度要求、入参是否在枚举值范围内等等。日常开发中,很多低级bug都是不校验参数导致的。
比如下面代码,在进行业务操作前,需要做一系列的判断,保证接口参数的正确性
@Override
public ResponseResult delPicture(Integer id) {
//1.检查参数
if(id == null){
return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
}
WmMaterial wmMaterial = getById(id);
if(wmMaterial == null){
return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST);
}
//2.判断当前素材是否被应用
Integer count = wmNewsMaterialMapper.selectCount(Wrappers.<WmNewsMaterial>lambdaQuery().eq(WmNewsMaterial::getMaterialId, id));
if(count > 0){
return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID,"当前素材被引用,不能删除");
}
//3.删除OSS中的图片
fileStorageService.delete(wmMaterial.getUrl());
//4.删除数据库中的素材信息
removeById(id);
return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
}
除了手动添加参数校验外,还可以使用Springboot Validation框架对参数进行校验.
如下代码,如果是非空校验,则可以直接使用注解表示。
@Data
public class WmLoginDto {
/**
* 用户名
*/
@NotBlank(message = "用户名不能为空")
private String name;
/**
* 密码
*/
@NotBlank(message = "密码不能为空")
private String password;
}
三、更安全的接口
在现代应用系统中,接口安全至关重要,特别是在处理敏感数据和对外提供服务时。我们面临的场景包括:
- 内部管理系统:依赖token验证和Spring Security进行权限控制。
- 对外接口服务:需要数据加密、HTTPS通信、加签验签以及限流措施。
- 面向消费者的接口:实施token验证和限流策略。
💡数据加密
对于对外提供的接口服务,敏感数据(如手机号、邮箱、身份证号、密码等)必须加密处理,以满足网络安全和监管要求。
对称解密
- 优点:加密速度快,适合大量数据处理。
- 缺点:密钥管理复杂,一旦泄露,安全性将大打折扣。
- 应用:适用于非持久化存储的敏感信息加密。
非对称加密
- 优点:安全性高,公钥加密私钥解密,难以破解。
- 缺点:加密解密速度慢,适合少量数据的加密。
- 应用:适用于传输过程中少量敏感数据的加密。
💡使用Https协议
HTTPS通过SSL/TLS协议确保数据传输的安全性、完整性和身份认证。HTTPS证书需从可信的云平台(如阿里云、腾讯云)购买,以确保通信安全。
Https是安全性也是通过对称加密和非对称加密来完成的,详细的交互流程如下图:
执行流程:
- 身份验证:客户提交身份证明文件给服务提供商,后者验证后颁发包含公钥A和公司信息的数字证书。
- 证书验证:客户使用数字证书访问网站,客户端验证证书合法性。若合法,提取公钥A并生成随机秘钥KEY。
- 数据传输:客户端用私钥B加密KEY,服务器用私钥B解密获取KEY。双方随后使用KEY进行对称加密通信,确保数据安全。
💡限流
接口限流可防止服务过载、抵御恶意攻击、提升服务质量、保护后端服务及应对突发流量。通过限制请求次数,保护服务器资源,确保系统稳定性。限流策略包括基于Tomcat限流、令牌桶算法、漏桶算法,适用于不同业务场景。
常见的限流策略:
-
Tomcat限流
- 方式:设置最大连接数。
- 应用:适用于单体项目,集群环境下最多支持5台。
-
漏桶算法
- 原理:基于IP限制请求速率,超出桶容量的请求将被丢弃。
- 优点:简单易用,能有效控制请求速率。
-
令牌桶算法
- 原理:令牌以固定速率生成,请求消耗令牌,无令牌时请求被延迟或丢弃。
- 优点:既能控制平均速率,又能应对突发流量。
- 实现:Spring Cloud Gateway、Sentinel等组件支持。
方案一:tomcat限流
适用于单体项目,可以设置tomcat的最大连接数进行限流
在tomcat中的配置文件server.xml中,找到如下配置,可以修改maxThreads="200"
来设置连接数
<Connector port="8080"
protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
maxThreads="200"
acceptCount="100" />
方案二:Nginx 漏桶算法
漏桶算法(Leaky Bucket)是一种常用的流量控制算法,广泛应用于网络流量整形和速率限制。其原理类似于一个装水的桶,桶底有一个固定速率的孔,水(请求)从桶顶注入,并以恒定速率从桶底流出。当注入的水量超过桶的容量时,多余的水会溢出(丢弃)。
- 桶的容量:代表当前系统或队列能够处理的请求数的上限。
- 流出速率:桶底的孔以固定的速率排出请求,表示系统处理请求的能力。
- 溢出:如果请求到达的速率超过了桶的流出速率,并且桶已满,则多余的请求将被丢弃。
漏桶算法可以根据用户的IP进行限流,可以设置每秒访问的请求数,我们可以配合nginx来完成漏桶算法
http {
limit_req_zone $binary_remote addr zone=servicelRateLimit:10m rate=10r/s
server {
listen 80;
server_name localhost;
location /{
limit_req_zone = servicelRateLimit burst=20 nodelay;
proxy_pass http://targetserver;
}
}
}
语法:limit_req_zone key zone rate
- key:定义限流对象,binary_remote_addr就是一种key,基于客户端ip限流
- Zone:定义共享存储区来存储访问信息,10m可以存储16wip地址访问信息
- Rate:最大访问速率,rate=10r/s 表示每秒最多请求10个请求
- burst=20:相当于桶的大小
- Nodelay:快速处理
方案三:令牌桶算法
令牌桶算法通过维护一个“桶”来控制数据的发送速率。桶内存储一定数量的“令牌”,每个令牌代表一个数据包的发送权限或一定量数据的处理能力。令牌以固定的速率生成,并被添加到桶中。数据包的发送需要消耗令牌,如果桶内没有令牌,则数据包需要等待,直到有令牌可用。
- 令牌桶:一个虚拟的容器,用来存放固定数量的令牌。桶的大小(即容量)决定了系统可以累积的令牌数量,从而决定了系统能够应对的最大突发流量。
- 令牌填充速率:系统以固定的速率向桶中添加令牌。这个速率决定了系统允许的平均流量速率。增加令牌生成速率可以提高系统的平均处理速率,但也可能导致更多的突发流量。
- 令牌消耗:每当一个数据包发送时,就从桶中移除一定数量的令牌。令牌的数量与数据包的大小相关,通常一个令牌代表一个字节或固定大小的数据包。如果桶中没有令牌,数据包将被延迟发送或丢弃,直到桶中有足够的令牌。
- 可解决突发流量
- 令牌桶算法可以使用Spring Cloud Gateway网关中的局部过滤实现
四、结语
在本文中深入剖析了接口设计的全流程,从规范到安全,再到限流策略,为开发者提供了全面的指导。接口设计的四大要素和测试方法确保了接口的高效与稳定。同时,参数校验、数据加密、HTTPS通信等安全措施进一步提升了接口的可靠性。未来,接口设计将更加注重用户体验和安全性,如引入更智能的限流算法、加强身份验证等,以应对日益复杂的网络环境。
五、好消息
为解决一站式学习、面试等问题,黑马程序员推出了【黑马智学伴侣】平台。该平台汇聚大咖老师,致力于解决你的学习、面试、升职等一系列问题,成为你的坚实后盾。 现在,只需轻轻一扫下方二维码,或点击下方链接,即可立刻加入「黑马智学伴侣」知识星球,享受我们为您提供的专属服务:
点击链接,轻松加入知识星球:t.zsxq.com/TZS1s 即刻成为知识星球的一员:
注:三天内,如果你不满意,就算你已经领了资料、享受了服务,我们也承诺给你全额退款,绝不二话!