当前位置: 首页 > news >正文

API接口设计的18条规范

API接口设计的18条规范

签名

目的:防止数据被篡改

实现方法:

  1. 接口请求方将请求参数、时间戳和密钥拼接成一个字符串
  2. 使用MD5等hash算法生成签名sign
  3. 在请求参数或请求头中增加sign参数,传递给API接口
  4. API接口网关服务验证传递的sign值,与自己生成的sign值对比,若相等则认为是有效请求

时间戳的作用:防止同一次请求被反复利用,增加密钥未破解的可能性,每次请求设置合理的过期时间,如15分钟。

加密

目的:保护敏感数据,如密码、银行卡号等

实现方法:

  1. 使用AES对称加密算法
  2. 在前端使用公钥加密用户密码
  3. 在注册接口中使用密钥解密并做相关校验

加密方式的选择有很多,如AES, RSA等等,可以根据自己实际需要选择合适的加密方式。

IP白名单

目的:防止恶意请求
实现方法:

  1. 限制请求IP
  2. 添加IP白名单在API网关服务上
  3. 防止内部服务器被攻破,需增加WAF (web防火墙软件,如ModSecurity、OpenWAF等)

限流

目的:限制单位时间内用户的请求数量,防止API接口被频繁调用导致服务不可用。
实现方法:

  1. 对请求IP、请求接口、请求用户做限流
  2. 使用nginx,redis,gateway ,sentinel 等技术实现限流功能

请求方式

目的:根据实际业务,选择合适的请求方式,如restful风格或自定义风格等等,怎么合适怎么来

具体方法:

  1. 不建议让前端做主选择api请求方式,(之前遇到过不靠谱的前端非要求后端把一个删除接口从delete请求改成get接口,争论几番后原来是他不太会用axios就给后端找事)
  2. 个人建议,如果是非常简单的CRUD业务,可以使用restful风格,如 查询/分页接口用GET ,添加/新增接口POST ,修改/更新接口用PUT ,删除接口用 DELETE
  3. 遇到一些特殊的业务接口,如发布按钮,用POST请求,带上时间戳和其他请求参数;
  4. 再比如 前端有一个下拉框接口,下拉选择时要支持动态手输新增item (可以参考elementUI中的下拉框组件高级特性),这个时候对后端就有高要求了,要一个接口既支持返回arraylist ,也支持传入一个新item值,当前端没传item值,返回现有的arraylist,当前端输入了一个item值,后端先添加这个item值到数据库,再执行查询返回最新的arraylist给前端,这个后端逻辑不难,但是要注意得用POST接口实现,来标识该接口所做的业务是非幂等的。

参数校验

目的:拦截无效请求,保护系统资源
实现方法:

  1. 校验字段是否为空、字段类型、字段长度、枚举值等
  2. 使用Hibernate Validator 等框架进行参数校验,使用注解如 (@NotNull @NotBlank @NotEmpty @Size @Max @Min等)对字段进行限制。

请求头设计

目的:将公共参数放入请求头中,便于后端统一拦截处理

实现方法:

  1. 前端登录成功后,让前端把jwt放到请求头里,后续再请求后端,后端就可以知道请求的用户等信息
  2. 一些重要的业务请求,让前端在请求头里加上traceId,便于后端做幂等处理
  3. 一些重要的资源,若没有规定的特殊的请求头,不允许上传或下载
  4. 一些对外开放的openApi ,限定外部请求时必须加上规定的请求头来做权限验证和请求来源识别
  5. 可以通过请求头中的user-agent来限定请求来源,如禁止PC端访问,只允许手机端访问

统一异常返回

目的: 避免异常返回结构不统一,便于接口维护
实现方法:

  1. 法一–在SpringBoot中使用GlobalExceptionHandler处理全局异常
  2. 法二–项目中有网关如SpringGateway时,所有异常通过API网关捕获并转换成统一的异常结构返回

统一封装返回

目的:以相同格式返回数据,便于前端接收处理,节省前端数据转换处理的代码

实现方法:
构造一个如下2种格式的json返回封装

{
"code": 20001,  //业务返回码
"success": true, //标识请求成功/失败
"message": "查询数据成功",  //返回的业务处理消息提示
"timestamp" : 1718506205 , //时间戳
"result" : [  ]  //返回的数组数据,array内部还可以继续有obj
}
{
"code": 20001,  //业务返回码
"success": true, //标识请求成功/失败
"message": "查询数据成功",  //返回的业务处理消息提示
"timestamp" : 1718506205 , //时间戳
"result" : {    //返回的对象数据,obj内部还可以继续有array"age":28 , "hobby":["reading","working"]} 
}

请求日志

目的:便于快速分析和定位问题
实现方法:

  1. 使用过滤器、拦截器或AOP实现记录请求URL、参数、请求头、请求方式、响应数据、响应时间
  2. 使用traceId 在整个请求日志中打标记,(可以参考我之前的文章 利用MDC实现日志打点 )https://blog.csdn.net/ThinkPet/article/details/131056402
  3. 也可以把日志转发到ELK中,后续在Kibana平台可视化查看日志

幂等设计

目的:防止多次请求产生错误数据
实现方法:

  1. 使用数据库唯一索引或redis保存requestId和请求参数来保证幂等性
  2. 如果使用了MQ组件,要在发送的mq消息内容中自定义messageId 即业务消息id ,并利用本地消息表来实现最终一致性

限制请求的数据量

目的:避免接口超时问题
实现方法:

  1. 限制查询接口请求查询的数据量(如一次最多返回30条记录)
  2. 限制批量保存接口入参的数据量(如一次最多同时保存5条)
  3. 超过限制直接提示用户

压测

目的:了解各接口的QPS情况,确保上线后的稳定性

实现方法:

  1. 使用Jmeter 或wrk 等测试工具进行压力测试
  2. 使用Prometheus ,Grafana等监控工具,监控api接口在测试环境的QPS

批量操作

目的:加快处理逻辑,一定程度上可以降低api超时时间

实现案例:

  1. 后端接口逻辑中,同类型数据执行批量保存,减少jdbc时间
  2. 上传接口要支持多图上传
  3. 删除接口要支持按ids删除1个或多个
  4. 大数据场景下,导入接口要支持单文件或多文件数据批量导入,后台分批次多线程处理写入
  5. 大数据场景下,导出接口可以分批次多线程查询数据,然后合并结果并导出excel文件

异步处理

目的:同步转异步,当前端一个接口要触发后端多个长逻辑时,经过仔细分析考量后,确认哪些逻辑可以转异步执行的,然后进行异步处理,提升复杂业务逻辑的接口性能。

实现方法:

  1. 利用MQ组件,一些实时性要求低的操作,把操作数据发送到MQ,然后让MQ消费者订阅后再执行操作处理。这样API接口发送MQ消息后立即返回成功,消息会由MQ消费者异步处理完成。
  2. 利用juc并发工具来对后端逻辑中的多个操作进行异步编排,如下
    CountDownLatch----允许一个或多个线程等待其他线程完成操作,它可以用来实现线程之间的等待和协调;
    CyclicBarrier----用于实现多个线程之间的屏障,它可以让一组线程等待,直到所有线程都到达指定的屏障点;
    CompletableFuture----jdk8提供的强大的异步编排工具,可以组合多个异步任务,实现串行执行,合并结果,异常处理等操作。

单一职责

目的:一个API接口尽量只做一个单一的业务操作。(实际开发中可能因为赶时间、降低前端难度等原因,经常要后端一个接口做多个复杂业务,这实际是项目技术债务)

设计思路:

  1. 尽量开发前,产品需求前后端人员有充足的会议讨论,共同设计一个 简单易用同时方便前后端开发的产品。
  2. 比如,原型设计中多使用 步骤条,穿梭框 等UI组件,把复杂业务流程简单化,而不是一味推给后端搞。建议原型设计多参考 AntDesignUI 和elementUI 提供的各种UI组件,大厂不是平白无故开发这些组件的,那都是为了实现各种需求,搞的设计思路。
  3. 不要搞方便了自己,麻烦了别人的做法。有些时候,UI的具体实现是 应该前端做es6的查询过滤排序等操作;有的时候,UI的实现中应该后端直接提供过滤、排序后的数据;还有就是 不要让前端同学生成id数据,虽然我知道前端领域有vue-uuid这种组件,但是我认为id数据应该后端产生,前端查询和使用。
  4. 要根据UI原型和业务需求,综合考量前后端的工作细节项。避免出现 方便了前端,麻烦了后端;或方便了后端,麻烦了前端。

数据脱敏

目的:数据部分加密后展示给前端,用来保护姓名、手机号等隐私数据,防止泄露隐私
实现方法:

  1. 用星号替代部分内容,如手机号132*****153
  2. 用预设的文本做内容替代,如 王先生/女士

完善的接口文档或API用例

目的:减少沟通成本,便于前后端对接API

具体方法:

  1. 法一—使用swagger 或knife4j 实现在线API接口文档,随服务启动而启动,让前端同学自己去看去对接;不过swagger 或knife4j 都对后端代码有侵入性,如果项目没有太高性能要求,可以使用这种方式。

  2. 法2----后端使用postman自测接口后,导出postman的apijson文件给前端,让前端把apijson文件导入自己的postman中,然后前端根据postman测试用例,自己开发前端axios请求逻辑;但前提是后端在使用postman自测接口时,完善的标记好字段含义,字段示例值等描述信息

相关文章:

API接口设计的18条规范

API接口设计的18条规范 签名 目的:防止数据被篡改 实现方法: 接口请求方将请求参数、时间戳和密钥拼接成一个字符串使用MD5等hash算法生成签名sign在请求参数或请求头中增加sign参数,传递给API接口API接口网关服务验证传递的sign值&#…...

adb简单使用命令

1. 查看当前连接的设备 adb devices 2. 文件路径 adb install apk 注意文件路径中不能有中文 3. adb shell ps Toplogcatlogcat可以结合greplogcat *:w 显示警告级别以上de 4. adb uninstall 软件名 1.软件名如何查看? 使用命令adb shell pm list packages会…...

构建 deno/fresh 的 docker 镜像

众所周知, 最近 docker 镜像的使用又出现了新的困难. 但是不怕, 窝们可以使用曲线救国的方法: 自己制作容器镜像 ! 下面以 deno/fresh 举栗, 部署一个简单的应用. 目录 1 创建 deno/fresh 项目2 构建 docker 镜像3 部署和测试4 总结与展望 1 创建 deno/fresh 项目 执行命令…...

数据库 | 数据库设计的步骤

1.需求分析 调查机构情况与熟悉业务活动,明确用户的需求,确定系统的边界,生成数据字典和用户需求规格说明书 2.概念结构设计 将从需求分析中得到的用户需求抽象为概念模型,设计E-R模型 3.逻辑结构设计 将E-R图转换为和DBMS相…...

改进YOLO系列 | CVPR 2021 | Involution:超越convolution和self-attention的神经网络算子

Involution:超越卷积和自注意力的新型神经网络算子(中文综述) 简介 Involuton是CVPR 2021上提出的新型神经网络算子,旨在超越卷积和自注意力,提供更高效、更具表达力的特征提取能力。 Involution原理 Involution的…...

落地速度与效果之争,通用VS垂直,我的观点和预测。

标题:AI大模型战场:通用VS垂直,谁将领跑落地新纪元? 摘要:随着人工智能技术的飞速发展,大模型的应用场景日益广泛。在这场竞赛中,通用大模型和垂直大模型各有优势,落地速度和可能性也…...

【Android面试八股文】在Android中,出现ClassNotFound的有可能的原因是什么?

在Android环境下类未找到的可能原因 在Android环境下,类未找到的可能原因包括但不限于以下几点: 类路径问题:Android应用使用的类通常存储在APK文件中。如果类所在的APK文件没有被正确加载,或者应用的类路径配置有误,就会导致类未找到的错误。 多DEX文件加载问题:在一些…...

模板引擎与 XSS 防御

在 View 层,可以解决 XSS 问题。在本书的“跨站脚本攻击”一章中,阐述了“输入检查” 与“输出编码”这两种方法在 XSS 防御效果上的差异。XSS 攻击是在用户的浏览器上执行的, 其形成过程则是在服务器端页面渲染时,注入了恶意的 H…...

vue3轮播图怎么做

先看效果 实现代码 <n-carouseleffect"card"dot-type"line"draggable:autoplay"!isHovered":current-index"currentIndex"prev-slide-style"transform: translateX(-150%) translateZ(-450px);opacity:1"next-slide-st…...

ubuntu中安装docker并换源

使用 Ubuntu 的仓库安装 Docker sudo apt update现在&#xff0c;你可以使用以下命令在 Ubuntu 中安装 Docker 以及 Docker Compose&#xff1a; sudo apt install docker.io docker-composeDocker 包被命名为 docker.io&#xff0c;因为在 Docker 出现之前就已经存在一个名为…...

HTML静态网页成品作业(HTML+CSS)—— 环保主题介绍网页(5个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有5个页面。 二、作品演示 三、代…...

深入了解RSA加密算法

目录 前言 一、什么是RSA&#xff1f; 二、RSA加密的基本概念 1.非对称加密 2.密钥生成 3.加密和解密 三、RSA加密的工作原理 四、RSA的应用场景 五、RSA加密解密的实现 六、RSA算法的局限性及改进措施 前言 在当今的数字化时代&#xff0c;信息的安全性成为了人们关注…...

github基础使用

前言 将用到的github指令记录下来&#xff0c;持续更新&#xff0c;方便随时查找学习。 一、github用到的指令 1、我们从github克隆下来的代码版本一般都是master主分支&#xff0c;我们要建立自己的分支进行修改&#xff1a; //git branch //查看目前的分支/* * master /…...

Docker使用心得

Docker使用心得 最近使用Docker比较频繁&#xff0c;特此想记录一下&#xff0c;方便后续查找。 Docker常用命令Docker如何配置使用GPU环境&#xff1f;如何使用Dockerfile构建镜像&#xff1f;如何使用docker compose 实例化容器&#xff1f; Docker如何配置使用GPU环境 参…...

QListWidget 插入 item,item显示自定义界面

代码示意&#xff1a; class ItemWidget_action_cfg_w(QWidget):... # 如下方法是在指定item下插入新的item def __do_add_item(self, item):# 获取当前item rowrow self.__list_w.indexFromItem(item).row()# 注意这里没有父类&#xff0c;解释见后面说明new_item QList…...

Python写一个ERP系统和agent智能体协同仓库和订单的案例

这是一个关于使用Python编写一个简单的ERP系统&#xff0c;并与Agent智能体协同完成仓库和订单管理的案例。在这个案例中&#xff0c;我们将使用Python的第三方库sqlite3进行数据库操作&#xff0c;以及discord库实现与Agent智能体的通信。 1. 首先&#xff0c;安装所需库&…...

【计算机网络】已解决:“‘ping‘ 不是内部或外部命令,也不是可运行的程序或批处理文件”报错

文章目录 一、问题分析背景二、可能出错的原因三、错误代码示例四、正确解决方法与示例五、注意事项 已解决“‘ping’ 不是内部或外部命令&#xff0c;也不是可运行的程序或批处理文件”报错 一、问题分析背景 在Windows操作系统中&#xff0c;ping 命令是一个常用的网络诊断…...

Web前端学堂:深入探索前端开发的核心领域

Web前端学堂&#xff1a;深入探索前端开发的核心领域 在数字化时代的浪潮中&#xff0c;Web前端开发扮演着至关重要的角色。它不仅是连接用户与互联网世界的桥梁&#xff0c;更是创造丰富、互动网络体验的关键所在。本文将带领读者走进Web前端学堂&#xff0c;从四个方面、五个…...

Java数据结构与算法(0/1背包问题)

前言: 背包问题&#xff08;Knapsack Problem&#xff09;是组合优化问题中的一个经典问题&#xff0c;有多个变种。这里我们讨论的是 0/1 背包问题&#xff0c;这是最基本的一种形式。问题的描述如下&#xff1a; 给定 n 件物品&#xff0c;每件物品有一个重量 wi 和一个价值…...

LLVM 中 的 pass 及其管理机制

概述 LLVM 编译器框架的核心概念是任务调用和执行 编译器开发者将IR分解为不同的处理对象&#xff0c;并将其处理过程实现为单独的pass类型。在编译器初始化&#xff0c;pass被实例化&#xff0c;并被添加到pass管理中 pass 管理器(pass manager) 以流水线的方式将各个独立的…...

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…...

React Native 导航系统实战(React Navigation)

导航系统实战&#xff08;React Navigation&#xff09; React Navigation 是 React Native 应用中最常用的导航库之一&#xff0c;它提供了多种导航模式&#xff0c;如堆栈导航&#xff08;Stack Navigator&#xff09;、标签导航&#xff08;Tab Navigator&#xff09;和抽屉…...

使用分级同态加密防御梯度泄漏

抽象 联邦学习 &#xff08;FL&#xff09; 支持跨分布式客户端进行协作模型训练&#xff0c;而无需共享原始数据&#xff0c;这使其成为在互联和自动驾驶汽车 &#xff08;CAV&#xff09; 等领域保护隐私的机器学习的一种很有前途的方法。然而&#xff0c;最近的研究表明&…...

STM32F4基本定时器使用和原理详解

STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...

如何在最短时间内提升打ctf(web)的水平?

刚刚刷完2遍 bugku 的 web 题&#xff0c;前来答题。 每个人对刷题理解是不同&#xff0c;有的人是看了writeup就等于刷了&#xff0c;有的人是收藏了writeup就等于刷了&#xff0c;有的人是跟着writeup做了一遍就等于刷了&#xff0c;还有的人是独立思考做了一遍就等于刷了。…...

[大语言模型]在个人电脑上部署ollama 并进行管理,最后配置AI程序开发助手.

ollama官网: 下载 https://ollama.com/ 安装 查看可以使用的模型 https://ollama.com/search 例如 https://ollama.com/library/deepseek-r1/tags # deepseek-r1:7bollama pull deepseek-r1:7b改token数量为409622 16384 ollama命令说明 ollama serve #&#xff1a…...

MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用

文章目录 一、背景知识&#xff1a;什么是 B-Tree 和 BTree&#xff1f; B-Tree&#xff08;平衡多路查找树&#xff09; BTree&#xff08;B-Tree 的变种&#xff09; 二、结构对比&#xff1a;一张图看懂 三、为什么 MySQL InnoDB 选择 BTree&#xff1f; 1. 范围查询更快 2…...

uniapp 小程序 学习(一)

利用Hbuilder 创建项目 运行到内置浏览器看效果 下载微信小程序 安装到Hbuilder 下载地址 &#xff1a;开发者工具默认安装 设置服务端口号 在Hbuilder中设置微信小程序 配置 找到运行设置&#xff0c;将微信开发者工具放入到Hbuilder中&#xff0c; 打开后出现 如下 bug 解…...

API网关Kong的鉴权与限流:高并发场景下的核心实践

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 引言 在微服务架构中&#xff0c;API网关承担着流量调度、安全防护和协议转换的核心职责。作为云原生时代的代表性网关&#xff0c;Kong凭借其插件化架构…...

Sklearn 机器学习 缺失值处理 获取填充失值的统计值

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 使用 Scikit-learn 处理缺失值并提取填充统计信息的完整指南 在机器学习项目中,数据清…...