本项目是一个面向开发者的 API 平台,提供 API 接口供开发者调用。用户通过注册登录,可以开通接口调用权限,并可以浏览和调用接口。每次调用都会进行统计,用户可以根据统计数据进行分析和优化。管理员可以发布接口、下线接口、接入接口,并可视化接口的调用情况和数据。本项目侧重于后端,涉及多种编程技巧和架构设计层面的知识。
思考
后端项目现在有 backend、interface,为什么不在一个工程呢?
因为平台可以接入任何人开发的接口,不一定是同一个团队或者公司内部的项目。
接口调用次数的业务流程
需求:
- 用户每次调用接口成功,次数 + 1
- 给用户分配或者用户自主申请接口调用次数
业务流程:
- 用户调用接口(之前已完成)
- 修改数据库,调用次数 +1
实际上,整个接口调用次数加 1 的业务流程是嵌入在我们调用接口的业务流程中的。
首先用户在前端看到接口,然后他要开通接口获取调用次数,获取调用次数后发起调用。
在原有的调用接口成功基础上,再添加一个步骤,即在统计次数的位置进行记录。
设计库表
既然每次调用接口成功都要加 1 次数,那我们需要区分是哪个用户调用了哪个接口
根据需求分析,这是一个多对多的关系,一个用户可以调用多个接口,而一个接口也可以被多个用户调用。
设计一个新的表来存储用户和接口之间的关系,可称之为"用户调用接口关系表"。
-- 用户调用接口关系表
create table if not exists yuapi.`user_interface_info`
(
`id` bigint not null auto_increment comment '主键' primary key,
`userId` bigint not null comment '调用用户 id',
`interfaceInfoId` bigint not null comment '接口 id',
`totalNum` int default 0 not null comment '总调用次数',
`leftNum` int default 0 not null comment '剩余调用次数',
`status` int default 0 not null comment '0-正常,1-禁用',
`createTime` datetime default CURRENT_TIMESTAMP not null comment '创建时间',
`updateTime` datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间',
`isDelete` tinyint default 0 not null comment '是否删除(0-未删, 1-已删)'
) comment '用户调用接口关系';
总调用次数:指用户从第一次开通接口开始至今累计的调用次数。
剩余调用次数:指用户每次购买接口后剩余的可调用次数。
状态字段(status):决定是否允许其调用特定接口。
- 为了增加安全性,我们可以考虑为每个用户设置一个状态字段(status),来决定是否允许其调用特定接口。这样,如果用户触发了某些规则或违反了规定,我们可以将其状态设置为不允许调用该接口。通过添加一个状态字段,我们可以灵活地管理用户对接口的访问权限。例如,当用户违反规则时,我们可以限制其对某些接口的调用,而对其他接口仍然保持开放。这个状态字段可以帮助我们实现精确的接口访问控制。
💡 不建议将调用时间直接写入数据库
如果每个用户每次调用接口都要在数据库中新增一条数据,那么数据库表可能会变得非常庞大。建议使用日志来存储这些调用信息,可以将其记录在文件中,使用类似 ELK 等工具进行日志存储和分析。
OK创建表~~~
mybatisX 插件生成代码
表创建完成之后,现在去生成增删改查代码;
鼠标右键 user_interface_info 表 → MybatisX-Generator。
模块路径选择当前路径即可,它会生成到 src/main/java 下
点击 Next 点击 Finish
多了一个 generator包
,代码都生成在这里。
给实体对象中的 isDelete 加上 @TableLogic,表示是逻辑删除的字段。
迁移生成的代码
把 UserInterfaceInfo.java 拖到entity
包下。
把 UserInterfaceInfoMapper.java 拖到mapper
包下。
把 UserInterfaceInfoServiceImpl.java 拖到impl
包下。
把 UserInterfaceInfoService.java 拖到service
包下。
迁移完了,把generator
包删除,鼠标右键generator
包 → Delete。
然后我们再写一下 controller,复制 InterfaceInfoController.java;
粘贴到controller