Bruno 开源 API 开发与测试客户端深度解析:基于 Bru 文件的本地存储、Git 协作与全平台安装指南
本文围绕仓库中的波斯语 README(docs/readme/readme_fa.md)展开,全面讲解 Bruno 这一开源 API 客户端的核心设计理念——"集合即文件系统上的文本文件",包括其 Bru 标记语言的存储格式、离线优先与数据隐私立场、基于 Git 的团队协作模式,以及 macOS / Windows / Linux 三平台的多种安装方式,并结合仓库源码(
packages/bruno-lang等)给出可验证的实现依据。
1. Bruno 是什么:重新定义 API 客户端
Bruno 是一个开源的 API 客户端(项目自我定位为 Postman 等同类工具的变革者,仓库描述将其归为 Postman / Insomnia 的轻量级替代方案),用于 API 的探索、开发与测试。它的与众不同之处并不在于"能发请求",而在于数据存储方式与协作模式从根本上与主流工具不同。
与其把请求集合锁在云端数据库里,Bruno 选择了一条完全相反的技术路线(见 readme_fa.md 中"برونو مجموعههای شما را مستقیماً در یک پوشه روی فایلسیستم شما ذخیره میکند"一节):
你的 API 集合被直接保存在文件系统的一个文件夹中,集合中的每个请求对应一个使用纯文本标记语言 Bru 编写的文件。
这一设计带来两个立竿见影的效果:
- 集合就是你手边的普通文件:可以用任意编辑器查看、diff、批量替换;
- 版本控制天然可用:因为集合是文本文件,
git diff、git log、分支与合并都能精确到请求级别,这为下文第 3 节的"Git 协作"奠定了基础。
仓库的根目录 readme.md 与波斯语翻译版在这一点上的描述完全一致,可见这是整个项目最核心的架构决策。
1.1 项目仓库全景
当前仓库是一个 monorepo,以 packages/ 目录组织多个子包,从仓库目录结构可以看到与本主题直接相关的核心模块:
| 目录 | 职责(结合源码结构推断) |
|---|---|
packages/bruno-app |
基于 React 的桌面端 UI(包含 src/components、src/pages、src/providers 等大量源码) |
packages/bruno-electron |
Electron 桌面外壳与 IPC / 文件系统服务(src/ipc、src/services、src/store) |
packages/bruno-lang |
Bru 语言的解析器与序列化工具,负责 .bru 文件与内部 JSON 模型的互转 |
packages/bruno-cli |
命令行运行器,用于在无 GUI 环境下执行集合 |
packages/bruno-common |
跨端共享的类型定义与工具 |
其中 packages/bruno-lang 正是"集合即文本"这一核心设计的地基,我们在下一节结合它的源码与测试样例深入展开。
上图来自仓库 assets/images 目录,是 Bruno 主界面在仓库 README(如 readme_fa.md 中 [](https://gitcode.com/GitHub_Trending/br/bruno?utm_source=gitcode_repo_files))中使用的产品截图,用于展示其完整的请求编辑与响应查看工作区。
2. Bru 标记语言:集合的文本存储格式
2.1 Bru 是什么
Bru 是 Bruno 自研的一种纯文本标记语言,用于把一次 API 请求的全部信息(方法、URL、请求头、Query 参数、请求体、脚本、断言等)记录为可读、可 diff 的文本。这意味着集合无需专用数据库,一个普通文件夹 + 若干 .bru 文件就是一个完整集合。
仓库中提供了一个非常直观的示例文件 packages/bruno-lang/example/request.bru,其内容展示了经典 Bru(v1)书写风格:
type http-request
name Send Bulk SMS
method GET
url https://api.textlocal.in/bulk_json?apiKey=secret=&numbers=919988776655&message=hello&sender=600010
body-mode json
seq 1
params
1 apiKey secret
1 numbers 998877665
1 message hello
/params
headers
1 content-type application/json
1 accept-language en-US,en;q=0.9,hi;q=0.8
0 transaction-id {{transactionId}}
/headers
body(type=json)
{
"apikey": "secret",
"numbers": "+91998877665",
"data": {
"sender": "TXTLCL",
"messages": [{
"numbers": "+91998877665",
"message": "Hello World"
}]
}
}
/body
在这个示例中可以看到几个值得注意的要点:
- 元信息区:以
type http-request标识这是一个 HTTP 请求文档; - 键值对区(params / headers):通过
params ... /params、headers ... /headers这样的成对标签包裹列表; - 行内行的语义:在
headers与params中,每行形如标志位 键 值,其中标志位1表示启用、0表示禁用(例如示例中0 transaction-id {{transactionId}}表示该头当前被禁用);同时{{transactionId}}展示了 Bruno 的 模板插值(变量引用)语法; - 带类型的 body 区:
body(type=json)之后紧跟原始 JSON 内容,用/body结束,支持同一请求文件里并列多种 body 类型(示例中同时给出了 json 与 graphql 两种 body); - 脚本区:
script ... /script中可编写onRequest、onResponse等钩子函数,示例中onResponse内通过expect(response.status).to.equal(200)对响应状态码做了断言,这直接对应 Bruno 的脚本与测试能力。
2.2 Bru 语法解析的源码实现
从源码结构看,Bruno 在 packages/bruno-lang 中维护了两代 Bru 解析实现:
- v1 解析器位于 packages/bruno-lang/v1/src,目录下文件(如
params-tag.js、headers-tag.js、body-tag.js、script-tag.js、env-vars-tag.js、key-val-lines.js等)与上面 2.1 节的标签结构一一对应——params/headers这类"键值对区块"由key-val-lines.js配合各 tag 文件处理,body、script则有独立解析单元,验证了 Bru 是按标签分块的文本语法; - v2 解析器位于 packages/bruno-lang/v2/src,提供
bruToJson.js、jsonToBru.js、jsonToCollectionBru.js、envToJson.js、dotenvToJson.js等转换模块,说明 Bru 文件与内部 JSON 模型之间存在双向转换管线; - 测试样例:packages/bruno-lang/v2/tests/fixtures/request.bru 展示了新一代 Bru 的 YAML 风格块语法:使用
meta { ... }、get { url: ... }、params:query { ... }、auth:oauth2 { ... }、body:json { ... }、assert { ... }等花括号块代替 v1 的标签/标签配对,并用~前缀表示禁用某一行;collection.bru 则展示了集合级的meta { type: collection }、继承给请求的headers、auth、vars:pre-request、script:post-response等默认配置如何落盘为文本。
// 来自 packages/bruno-lang/v2/tests/fixtures/request.bru 的 v2 风格摘录
meta {
name: Send Bulk SMS
type: http
seq: 1
}
get {
url: https://api.textlocal.in/send/:id
body: json
auth: bearer
}
params:path {
id: 123
}
auth:oauth2 {
grant_type: authorization_code
authorization_url: http://localhost:8080/api/auth/oauth2/authorization_code/authorize
access_token_url: http://localhost:8080/api/auth/oauth2/authorization_code/token
client_id: client_id_1
client_secret: client_secret_1
pkce: false
auto_fetch_token: true
}
由上述两代语法样本与对应的解析器/测试文件可以看出:无论 Bru 语言如何演进,"把请求以可读文本落盘到普通文件夹"的架构始终未变——这正是一切 Git 协作与离线能力的根基。
3. 离线优先:为什么 Bruno 永不强制云端
在 readme_fa.md 的说明中有一句非常关键的产品立场声明:
Bruno 只以离线(offline)方式工作,未来也不计划加入任何云端同步功能。团队珍视用户的数据隐私,认为你的集合数据应当留在你自己的设备上。
这条原则与第 2 节"集合以文本文件存放在本地文件系统"的架构互为因果:
- 没有云端数据库,就不存在"数据上云"的隐私与合规顾虑;
- 团队如果想跨机器共享集合,不依赖厂商的同步服务,而是自己掌控载体——通常是 Git 仓库(详见第 4 节);
- 敏感信息(如示例中的 token、密码)始终位于团队自己的版本库与设备中。
也就是说,"本地优先 + Git 协作"不是妥协,而是 Bruno 针对 API 集合协作问题给出的明确架构答案,这也直接决定了它的使用方式与 Postman 等需要登录并同步到云端的工具截然不同。
4. 借助 Git 进行团队协作
既然集合是文件系统中的一个普通文件夹,那么协作方式就顺理成章:使用 Git,或任何你偏好的版本控制系统。
将集合目录纳入 Git 仓库后,团队可以享受到文本文件协作的全部红利:
- 代码评审式的集合审查:对某个请求的修改,可以像改代码一样发起 Pull Request / Merge Request,逐行审阅 Bru 文件的改动;
- 精确的变更历史:
git log能追踪到"谁在何时改动了哪个请求头、哪个 URL"; - 无冲突的并行开发:不同成员各改各的
.bru文件,冲突合并比二进制或云端存储简单得多; - 与现有研发流程无缝集成:集合跟着代码仓库走,分支、标签、回滚、CI 触发都复用同一套基建。
仓库目录中 packages/bruno-app(IDE 前端)与 packages/bruno-electron(桌面外壳及其 src/ipc、src/store 等文件系统相关模块)中包含了集合的装载、监控与写入逻辑,可以印证"集合在本地文件系统上实时读写"这条链路是 Bruno 运行时的核心路径。
上图来自仓库 assets/images 目录,用于说明集合作为文件夹/文本文件被 Git 跟踪、评审与版本管理的协作方式。
5. 跨平台支持
readme_fa.md 中单独用一节强调 Bruno 在多个平台上运行("روی پلتفرمهای مختلف کار میکند")。从仓库结构看,Bruno 的核心逻辑分为共享的 packages/bruno-app(UI)与 packages/bruno-electron(桌面运行外壳),这种架构天然支持各桌面平台共用同一套代码;而命令行的执行能力则沉淀在 packages/bruno-cli,可运行在服务器与 CI 环境,进一步拓宽了"跨平台"的边界。
作为开发者,你可以按需选用:在桌面端进行交互式探索与调试,在命令行或 CI 中执行同一套基于 Bru 文件的集合做回归测试——两端的输入输出模型一致,因为它们消费的是同一套文本集合。
上图同样出自 assets/images 目录的 README 配图,示意 Bruno 客户端可运行于多类桌面操作系统。
6. 安装指南:macOS / Windows / Linux
6.1 二进制安装包
官方为 macOS、Windows 与 Linux 提供了现成的二进制安装包,可从官网下载页面直接获取对应平台的安装文件(在 readme_fa.md 中被列为最直接的安装途径)。
6.2 通过包管理器安装
除二进制包外,官方还支持多种主流包管理器。原文给出了四条最常用的命令,下面逐一展开并补充说明:
# macOS —— 通过 Homebrew
brew install bruno
# Windows —— 通过 Chocolatey
choco install bruno
# Linux —— 通过 Snap
snap install bruno
在 Linux 上,Snap 安装通常需要系统已启用 snapd 服务;若你的发行版未预装 snapd,需先安装并启用它再执行上述命令。
仓库英文主 README(readme.md)中还额外列出了 Windows 的 Scoop / winget、Linux 的 Flatpak、Arch Linux 的 AUR 等途径(如 scoop install bruno、winget install Bruno.Bruno、flatpak install com.usebruno.Bruno、yay -S bruno),需要更多发行版覆盖时可一并参考。
6.3 Linux 下通过 Apt(Debian / Ubuntu)安装
针对 Debian / Ubuntu 系发行版,官方推荐通过 Apt 安装,完整步骤如下(自 readme_fa.md 原样继承):
# 1. 创建 keyring 目录
sudo mkdir -p /etc/apt/keyrings
# 2. 更新软件源并安装 gpg 与 curl
sudo apt update && sudo apt install gpg curl
# 3. 导入官方 GPG 公钥并写入 keyring
curl -fsSL "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x9FA6017ECABE0266" \
| gpg --dearmor \
| sudo tee /etc/apt/keyrings/bruno.gpg > /dev/null
# 4. 为 keyring 设置读取权限
sudo chmod 644 /etc/apt/keyrings/bruno.gpg
# 5. 写入官方 Apt 软件源(amd64)
echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/bruno.gpg] http://debian.usebruno.com/ bruno stable" \
| sudo tee /etc/apt/sources.list.d/bruno.list
# 6. 更新软件源并安装 bruno
sudo apt update && sudo apt install bruno
对以上步骤做几点实操补充:
- 步骤 3 中
0x9FA6017ECABE0266是软件源签名所用的 GPG 公钥指纹,安装前请确认该指纹可信; - 步骤 5 的
signed-by指向步骤 3 生成的 keyring 文件,若自定义过 keyring 路径需保持一致; - 若 CPU 架构非 amd64,需确认官方源是否提供对应架构的
arch条目后再修改源配置; - 安装完成后即可从应用菜单启动 Bruno,或通过终端命令直接唤起。
7. 入门之后的进阶资源
readme_fa.md 在正文后整理了一组重要入口,此处按其在仓库内的对应关系整理为便于索引的清单:
- 官方文档与使用手册:覆盖 Bru 语法、脚本 API、环境变量等完整说明,建议作为日常查阅的一手资料;
- 长期愿景讨论与路线图:了解"离线优先、无云同步"等决策背后的完整论证(上述产品立场即源于此);
- 发布 / 价格与下载页:关注免费与付费功能边界以及各平台最新版本;
- 使用案例与经验分享:仓库鼓励用户在讨论区分享 Bruno 帮助到实际工作的场景,可作为评估与选型的参考。
若你希望在新的包管理器中分发 Bruno(如把 .bru 生态接入某发行版仓库或自建源),请参考仓库根目录的 publishing.md,其中说明了发布到新包管理器的流程与约定;英文主 readme.md 的对应章节也提供了同样指引。
8. 参与贡献与品牌许可
8.1 如何贡献
项目欢迎一切形式的贡献。如果你希望从代码层面改进 Bruno,请先阅读仓库根目录的 contributing.md 及其多语言版本(本项目对应的波斯语版位于 docs/contributing/contributing_fa.md)。
即使你不写代码,也可以通过报告 Bug、提交 Feature Request 的方式帮助项目——凡是能解决真实使用场景的反馈,都同样有价值。对波斯语使用者,上述贡献指南的波斯语译本已随仓库分发,降低了本地化贡献的门槛。
8.2 品牌与开源许可
- 商标(Trademark):
Bruno是由 Anoop M D 持有的注册商标; - Logo:源自 [OpenMoji] 项目,采用 CC BY-SA 4.0 许可;
- 代码许可:仓库整体以 MIT 许可开源,详见仓库根目录的 license.md。
从许可组合可以看出:项目代码对社区高度开放(MIT),同时通过商标条款保护 Bruno 这一名称不被滥用,属于典型的"开放代码 + 受控品牌"治理模式。
9. 小结:从文档到代码的关键结论
回到 docs/readme/readme_fa.md 这份波斯语 README,全文的技术主线可以浓缩为四句话:
- Bruno 是开源的 API 探索与测试 IDE,目标是为 Postman 等工具提供不一样的替代方案;
- 集合 = 文件系统文件夹中的
.bru纯文本文件,这一架构由 packages/bruno-lang 中的两代解析器(v1/src 与 v2/src)及配套测试夹具(如 request.bru、collection.bru)实证支撑; - 离线优先、不搞云同步,数据隐私与本地所有权是产品的一等公民;
- Git 是推荐的协作方式,配合多平台支持与 Homebrew / Chocolatey / Snap / Apt 等安装通道,个人与团队都可以低成本上手。
对于想深入"知其所以然"的读者,建议顺着 packages/bruno-lang 的解析器与测试、packages/bruno-app 与 packages/bruno-electron 的 UI 与文件读写链路继续阅读源码,你会对"文本即集合"这套设计有更具体的体感。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0631
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
HivisionIDPhotos⚡️HivisionIDPhotos: a lightweight and efficient AI ID photos tools. 一个轻量级的AI证件照制作算法。Python09
DragonOSDragonOS is an operating system developed from scratch using Rust, with Linux compatibility. It is designed for **Serverless** scenarios. 使用Rust从0自研内核,具有Linux兼容性的操作系统,面向云计算Serverless场景而设计。Rust00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00