ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

10MB轻量级API客户端Bruno:告别Postman臃肿,拥抱Git与CI高效联调

10MB轻量级API客户端Bruno:告别Postman臃肿,拥抱Git与CI高效联调 面对 Postman 越来越臃肿的安装包、越来越慢的启动速度还有动不动就弹出来的登录提醒我相信不少接口测试的老手心里都憋着一股火。我自己的电脑上Postman 从双击图标到真正能输入 URL慢的时候能转七八秒的圈这还是在 NVMe 固态硬盘上。直到我花了一个周末折腾了一圈开源工具最后锁定了这个安装包只有 10 MB 左右、冷启动不到 1 秒的轻量级替代品才算是把这块心头病给治好了。这篇文章不是要劝你立刻卸载 Postman而是想从一个实际干活的人角度聊聊这个轻量替代品到底是什么、它凭什么能做到这么小这么快、以及我把它接入日常工作流之后的真实体验。如果你正被 Postman 的内存占用和启动速度折磨或者团队里想找一套更贴近 Git 工作流的接口管理方案这篇文章应该能给你一些参考。1. 为什么我开始嫌弃 Postman以及 10MB 替代品到底是个什么来头先交代一下背景。我日常主要做服务端接口开发和联调Postman 从 7.x 版本用到现在说句公道话它的集合管理、环境变量、自动化测试这些功能确实成熟生态也完善。但最近一年我是越来越觉得它不对劲。首先是体积和资源占用。Postman 现在的安装包动辄几百 MB装完之后的缓存、索引、GPU 加速进程在任务管理器里一看内存占用轻轻松松上 1GB。我笔记本只有 16GB 内存平时要开 IDE、数据库客户端、浏览器一堆标签页再挂个 Postman内存直接见红。其次是启动速度哪怕是 10.13.6 这种新版本冷启动也得等好几秒中间那个 Loading 动画看得人着急。最让我烦的是强制登录和账号体系偶尔离线环境下想临时测个接口它还要你登录甚至有时候登录态过期了直接卡在登录页面进不去。所以我当时给自己提了个需求找一个接口调试工具启动要快、体积要小、最好不用登录、数据要能本地管理。后来逛 GitHub 的时候发现了这个方案——一个基于本地文件存储的 API 客户端安装包不到 11MB打开速度体感就是秒开界面风格和 Postman 很像但核心设计思路完全不同它以文件夹和 Markdown 文件的形式保存每一个请求整个项目就是一个纯文本目录天然适合用 Git 做版本管理。这个工具目前在国内外的开源社区热度都很高很多团队把它当成 Postman 的轻量替代方案来用。它的核心优势总结下来就三条一是底层基于 Web 技术但打包优化做得极其克制所以安装包能压在 10MB 出头二是启动时不加载远程资源、不做遥测同步所以冷启动速度飞快三是请求数据就是本地文件不锁库不绑定账号完全归你掌控。2. 安装部署与第一个请求从下载到发请求只要三分钟2.1 下载安装的那点事儿我是直接在 GitHub Releases 页面下载的对应自己系统的安装包。以 Windows 为例下载下来的安装包大概 10.6MB和其他动辄几百 MB 的“全家桶”比起来简直像是一个轻量级工具该有的样子。安装过程走的是系统安装器一路 Next 就行没有额外组件、没有后台服务、没有开机自启的常驻进程。装完之后我又特意看了一眼安装目录整个安装文件夹加起来也就 40MB 多一点点。你们要知道Postman 的安装目录随便都是 500MB 往上走的。这里顺便提一句官方也提供了免安装的 zip 压缩包解压即用适合放在 U 盘或者公司电脑上临时用。但这个我没实际用过因为我觉得还是正常安装版体验更完整。Linux 环境下也有对应的 AppImage 或者其他发行版打包格式Ubuntu 用户可以直接拉取仓库安装不需要像 Postman 那样手动配环境或者担心依赖缺失。如果你平时在服务器上做开发完全可以把请求集合的文件夹放到服务器上随手就能改、随手就能发。2.2 创建第一个请求时我发现的细节打开软件之后界面布局和 Postman 很相似左边是请求集合列表中间是请求编辑区右边是响应区。新建请求的时候它会问你存到哪个集合里这点和 Postman 操作逻辑是一样的。我随便填了一个测试接口的 URL选好 GET 方法点 Send响应几乎瞬间就回来了。虽然响应快主要归功于网络和服务端处理速度但工具本身的 UI 响应也很跟手不像 Postman 在高分屏下偶尔会有明显的输入延迟。有一个细节让我挺舒服新建请求时默认的请求文件名就是请求的描述内容比如我填了查询用户信息文件名就是查询用户信息.bru。这个 .bru 文件是个纯文本格式用文本编辑器打开就能看到完整的请求配置包括 method、url、headers、body 等等。熟悉 Postman 的你大概已经意识到这意味着什么了——它完全可以像管理代码一样管理接口定义每次修改都能通过 Git diff 一眼看出改了哪些字段。提示这个 .bru 文件格式是纯文本但如果团队里有人不太熟 Git建议还是先在 IDE 里装好相应的语法高亮插件避免有人直接改坏了文件格式。2.3 导入 Postman 旧数据迁移从 Postman 迁移过来最关心的就是历史数据能不能带过来。它支持直接导入 Postman 导出的 JSON 集合文件我在 Postman 里选中已有的集合右键导出为 v2.1 格式的 JSON然后在替代工具里选择导入瞬间所有请求和历史环境配置就都进来了。注意我这里说的是集合本身如果 Postman 里那些用脚本动态生成 headers 的预请求脚本导入进来之后可能需要手动整理一下毕竟两者的脚本语法都是基于 JS 的但执行时机和内置 API 略有差异。第一次导入完我特意抽查了几个带认证 token 的接口发现请求头、query 参数、路径参数基本都能完整迁移。不过 Postman 的 CryptoJS 写的 HMAC 签名脚本还是得自己重新翻译成新工具支持的脚本写法这个后面专门讲。3. 核心细节解析集合、环境变量和脚本这三个基本功到底怎么样3.1 集合的概念变成了真实文件夹在 Postman 里集合Collection是一个虚拟概念数据存在 Postman 自己的索引里你看不到它的物理存储结构。而这个替代工具把集合直接映射为文件系统里的真实目录每一个请求就是一个 .bru 文件目录层级就是集合的嵌套分类。这意味着你可以用文件资源管理器直接拖拽调整请求位置也可以在 IDE 里批量替换某些请求的 URL 前缀。更实用的是代码评审的时候可以直接在 GitLab 或 GitHub 上打开某个请求文件看它的完整配置不需要把工具打开再去翻找。我在实际项目里就把接口集合的目录和项目代码放在同一个仓库里前端、后端、测试共用一套接口定义。任何人改了接口提交代码的时候自动带上 .bru 文件变更Review 的人一眼就能看出接口改动是否同步更新了调试文档。这一点是 Postman 那种中心化云同步模式做不到的——它要么靠团队在 workspace 里协作要么得导出文件再传远没有 Git 天然分支管理来得顺滑。3.2 环境变量用起来和 Postman 差不多但有个坑环境变量这个东西做接口测试的人每天都离不开。开发环境一个 base URL测试环境一个 base URL有时候还有本地环境、预发布环境全靠环境变量来切。这个替代工具的环境变量配置方式和 Postman 类似先创建环境再在环境里配置键值对请求的 URL 里用双花括号语法 {{baseUrl}} 来引用变量。不过它有一个和 Postman 不一样的地方——除了环境级变量它还支持直接在集合级别定义变量而且优先级是请求文件里的变量定义大于集合变量、大于环境变量。初学时最容易踩的坑就在这如果你在一个集合里定义了名为 baseUrl 的变量又在环境里也定义了同名变量很可能你以为切换环境能改变 baseUrl实际上请求却一直走集合变量的值。我一开始就被这个现象迷惑过排查了半天才发现是变量优先级的问题。注意使用共享变量名之前一定先确认当前请求的 Variables 标签页是空白的。否则环境切到天边都没用请求用的还是文件里写死的那份变量值。3.3 脚本能力从简单断言到动态签名再来说说脚本。它支持在请求前Assert/Script 标签页写 JS 代码也支持在响应返回后写断言脚本。基础用法和 Postman 的 Pre-request Script 以及 Tests 脚本很类似常见的都有比如从响应 JSON 里提取某个字段作为变量供后续请求使用发送请求前用环境变量拼接出时间戳或者随机数对返回内容做断言比如校验状态码、校验响应体的某个字段但如果你在 Postman 里重度依赖了 require(crypto-js) 这类 Node.js 内置模块那迁移的时候要注意了——这个工具的运行环境不是完整的 Node.js很多内置模块是不支持的它只支持浏览器端的 Web API 以及内置提供的一些轻量工具方法。我项目里有个老接口的鉴权逻辑是基于 AES 加密的原本在 Postman 里用 CryptoJS 也就几行代码的事迁移过来之后发现没有 crypto-js 模块最后绕了一圈用了 Web Crypto API 的 crypto.subtle 才实现了同样的 AES 加密。如果你也有类似需求我的建议是先把 Postman 脚本里用到的外部依赖列个清单然后逐个确认替代工具是否支持。如果有不支持又绕不过去的优先考虑把它拆成一个独立的小服务通过 HTTP 调用来生成签名别硬在脚本里实现。4. 实操过程用这个工具跑通一个带完整鉴权和断言链路的接口测试4.1 场景设定和预期目标光说不练假把式。我拿一个实际项目举例某内部管理系统的登录接口逻辑是先获取一个带时间戳的签名再用签名换取 token最后带着 token 查询用户列表。这三个接口串起来就是一条完整的联调链路用来验证工具在真实业务场景下到底能不能扛住。我预期达到的目标有三个第一通过环境变量切换 dev 和 prod 两套环境的 base URL第二通过“接口间传递参数”的方式实现登录 token 自动写入后续请求的 header第三添加断言确保每次请求返回的 HTTP 状态码和关键字段符合预期。4.2 一步步操作的完整记录第一步创建一个集合命名为 用户中心联调在这个集合下新建三个请求分别是获取签名、登录换取token、查询用户列表。每个请求的 URL 都用 {{baseUrl}} 开头方便后续切环境。第二步创建两个环境dev 环境设置 baseUrl 为 http://dev-api.internal.example.comprod 环境设置 baseUrl 为 http://api.example.com。这里我故意用了 .internal 域名的样例实际按自己公司环境配就行。第三步配置获取签名请求的响应后脚本。这个请求返回的 JSON 形如 {data: {sign: xxxx}}我在脚本里写const body res.body; const json JSON.parse(body); bru.setVar(sign, json.data.sign);这里注意bru.setVar 设置的是“运行时变量”它不会永久写入环境配置文件只在当前运行时有效。这正好是我想要的效果——签名这种一次性数据根本不需要保存到环境里每次运行时现取现用即可。第四步配置登录换取token请求。请求体里需要携带 sign 参数我在请求体的原始 JSON 里直接写{ appId: 123456, sign: {{sign}} }发送前工具会自动把 {{sign}} 替换成上一步脚本写入的运行时变量。登录接口返回 {data: {token: eyJhbGciOi...}}我再在响应后脚本里写const json JSON.parse(res.body); bru.setVar(token, json.data.token);第五步配置查询用户列表请求在请求头里加上Authorization: Bearer {{token}}这样当集合里的请求按顺序执行时token 会自动注入不需要手动复制粘贴。第六步给查询用户列表请求添加响应断言。我想要的是既校验状态码又校验接口返回结构。在运行结果标签页里找到断言功能填写类似这样的检查项expect(res.status).to.equal(200); expect(json.data.list).to.be.an(array);这里的断言语法和常用的测试框架类似如果你已经熟悉 Postman 的 Chai 断言上手基本没什么难度。第七步用运行集合功能把这三个请求按照顺序跑一遍。跑完之后能清晰地看到每个请求的通过/失败状态。断言的最终结果也一目了然。4.3 运行机制和命令行的衔接这个工具还带了一个命令行工具这是它比 Postman 那套 Newman 流程更轻量的地方。我在 CI 流程里其实没有去调用 GUI而是直接用命令行跑集合里全部请求。官方文档里给了一种无头运行的方式命令大致长这样bru run 用户中心联调 --env dev这条命令会自动按顺序执行集合里的所有请求并输出测试报告。加上 --env 参数切环境非常方便。跑完的退出码是 0 还是非 0直接和 CI 的成败挂钩。我在公司内部就直接把它接进了 GitLab CI 里逻辑很简单每次有人改接口代码流水线里先把对应的 .bru 集合跑一遍如果接口返回结构变了导致断言失败流水线就会红倒逼开发者同步更新接口调试文档。这个流程对团队协作的帮助很明显尤其是前后端并行开发的时候后端接口一改前端马上就能通过测试报告发现问题不用再等人来通知。5. 常见问题与排查技巧实录5.1 环境变量不生效请求还是用的旧地址这个问题我碰到过两次第一次排查了半天后来发现自己新建的环境没有点“激活”按钮。它在环境切换上的交互和 Postman 略有不同Postman 是选一个环境就全局生效而它除了选择环境还要求当前请求没有手动覆盖的变量值。如果请求的 Variables 标签页里存在同名变量环境变量就会被忽略。解决办法先切换到目标环境然后打开具体请求确认 Variables 标签页为空再试。如果已经设置了变量又想去掉直接在 Variables 标签页里删除对应行即可。它本质上是“请求文件里的变量优先于环境变量”理解了这个规则就不会再困惑。5.2 中文乱码和字符编码问题接口联调最怕响应里返回一堆乱码。它在处理部分老系统接口时如果响应头没有明确 charsetutf-8可能因为默认按 UTF-8 解析而出现中文乱码。这个问题在 Postman 里也存在但 Postman 会根据响应头自动判断一些情况。我实际遇到的一次是某个 Java 老项目接口返回 JSON 但 Content-Type 是 application/json没有 charset 字段而实际编码是 GBK。这个工具按 UTF-8 解析就直接乱码了。解决办法有两个一是建议服务端加上 charsetutf-8这个治本二是在工具这边可以考虑先用命令行或者浏览器验证一下接口原始字节确认编码格式。不过说实话现在这种纯 GBK 的老接口越来越少了真遇到也就是特殊处理一下不会常驻影响日常开发。5.3 导入 Postman 的集合之后脚本失效了从 Postman 迁移的时候最麻烦的不是请求本身而是脚本。Postman 里的脚本使用了 pm.* 这一套全局 API而这个工具则使用 bru.* 的 API虽然很多命名很相似但直接拷贝是运行不了的。比如 Postman 里设置环境变量用的是 pm.environment.set(key, value)到这边就得改成 bru.setVar(key, value)。我第一次导入的时候集合里的 20 多个请求全部导入成功但几乎所有带脚本的请求都不能正常运行。当时我没逐个检查直接跑了集合结果是十几个请求全部报错以为是工具稳定性问题。后来点开一个请求才注意到脚本里还写着 pm.sendRequest 这种老 API这才意识到是需要翻译脚本的。如果你有大量 Postman 脚本需要迁移我给你一个技巧不要试图逐个请求去改先总结出你自己最常用的几个模式。像我自己的项目里无非就是“响应里取字段存变量”“根据环境变量构造 sign”“断言状态码”。把这三种模式在替代工具里各写一遍作为模板后续就是复制粘贴替换字段名的机械工作一两个小时就能处理完几百个请求。5.4 大响应体的性能表现还有一个场景是调试大接口有个搜索接口返回的是上万条记录JSON 体大概 8MB。在 Postman 里打开这种响应滚动查看的时候会有明显卡顿。而这个工具因为采用的是轻量渲染反而没有这个问题滚动流畅度好不少。不过它也没有 Postman 那种格式化的可视化 JSON 树大部分时候只能看原始 JSON 文本需要自己心里有数或者借助 IDE。对于日常排错来说纯文本 JSON 已经够用了。6. 工具选型之争它和 Postman 到底谁更合适6.1 不同场景下的选择建议不做选择题是不可能的。如果你只是一个人开发偶尔测个接口那选谁完全看心情。但如果你要考虑团队协作、CI 集成、离线环境、多环境管理这些因素那就有得聊了。适合迁移到轻量替代工具的场景项目代码本身就是 Git 管理希望接口调试文档和代码同步进仓库的对隐私敏感不希望所有请求记录都上传到云端的电脑配置一般Postman 一到手就卡得动不了的离线内网环境开发没法用 Postman 在线登录功能的需要把接口冒烟测试跑进 CI 流水线的命令行工具很有价值反过来如果你重度依赖 Postman 的云端 team workspace 协作、或者需要 Postman 的在线文档分享功能、又或者你的团队已经围绕 Postman 生态建立了完整的测试体系那暂时留到 Postman 也合理。毕竟迁移成本不在工具本身而在人。6.2 我在真实项目里的分工节奏我现在的工作方式是Postman 留在老项目里不动。新项目一律用轻量替代工具把 .bru 文件直接提交到 Git 仓库。日常本地调试、环境切换、快速验证都在新工具里完成只有需要临时看一下之前 Postman 里面的老集合定义时才打开一次 Postman。这让我电脑上的内存从常驻 1GB 降到了 300MB 左右风扇都不怎么转了。如果你也打算像我这样混着用记住一个原则同一个接口别在两个工具里同时维护不然两边定义漂移了反而更糟。新项目用新流程老项目有历史包袱就先维持原样等重构的时候再顺势迁移。7. 总结与下一步扩展用这个 10MB 出头的轻量替代方案替换掉 Postman是不是适合每个人我不敢打包票。但对我自己来说最大的收获不是省了那不到 1GB 的内存而是它把我从 Postman 账号、云同步、索引缓存这些“接口调试之外的事情”里解放了出来。启动快、数据本地化、文件即接口、命令行可跑 CI这些点真正契合了我日常的开发节奏。如果你决定试试我建议别急着整体迁移先把一两个常用的请求导进来发几个接口建一下环境变量感受下交互差异。然后选一个不重要的项目把集合目录提交到 Git 里体验一下接口文档跟着代码走的感觉。觉得顺手了再扩大迁移范围也不迟。就我个人实际使用体验来说这个工具的价值不在于它比 Postman 少了多少功能而在于它把和真正的测试调试无关的杂音全部剔除了留下的东西都足够日常使用。最后再分享一个小技巧把新建请求的快捷键和 IDE 里的 Git 提交键配合起来我现在的习惯是改完接口、写完断言、提交代码一条龙根本不用在两个窗口之间来回切测试代码和调试记录也不会出现“忘了更新 Postman”的尴尬情况。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进