在浏览器中安全测试复杂 jq 过滤器,无需担心生产数据泄露
有多少次你不得不在终端里盲目地拼装一个长长的 jq 表达式?这是很多人熟悉的场景:你发起一个 API 请求,得到几千行文本,然后反复按上箭头,添加管道符、选择器和切片。只要一个括号写错——终端就会报错或返回一个空数组。
这种情况下第一反应是打开某个在线格式化工具。但如果你处理的是生产日志、支付响应或用户个人数据,把它们粘贴到搜索结果里的随机网站是不可行的。
jq 开发团队原生解决了这个问题,发布了名为 playground 的官方沙箱。源代码在 GitHub 上以 MIT 许可证开源,访问地址为 play.jqlang.org。
这是什么
这个项目是一个交互式的 jq 网页工具。屏幕左侧粘贴源 JSON 或通过 URL 拉取,顶部编写过滤器,右侧即时显示转换结果。
这里的主要特性在底层。所有解析和过滤器执行都在你的机器本地进行。该服务不会将你的 JSON 内容发送到远程服务器。
这要归功于 jq-wasm 移植——该工具的原始 C 代码被编译为 WebAssembly。因此,浏览器独立执行繁重的转换,无需操作系统端的原生依赖。
沙箱在实践中的用处
与数十个来源可疑的无名服务不同,这个工具同时解决了多个实际任务。
首先,默认隐私保护。由于处理器直接在客户端的 WebAssembly 中运行,你可以安全地将内部数据库转储、基础设施配置或 API 数据上传到沙箱。只有当你粘贴外部 URL 来加载 JSON 时才会产生网络请求。
其次,方便的代码片段分享。当需要向同事演示如何正确解析第三方服务的畸形响应时,只需点击分享按钮。服务器会保存过滤器代码并生成短链接。链接接收者会在自己的浏览器中再次本地运行计算。
第三,响应式界面。由于无需网络往返传输数据,结果会在你输入过滤器时实时重新计算。对于调试 walk()、递归下降或自定义函数等复杂结构,这能节省大量时间。
第四,沙箱可以部署在自有网络边界内。如果你的公司在没有互联网访问的封闭网段中运行,项目可以轻松地在本地或内部团队服务器上启动。
内部结构:架构与技术栈
沙箱使用 TypeScript 和 Next.js 构建。应用结构非常简洁:
- 基于 React 的前端,集成了代码编辑器和
jq-wasm。 - PostgreSQL 数据库,仅用于存储分享的代码片段。
- 服务端 API 端点(
POST /api/jq),通过工作线程池在后台执行请求。
源代码中有一个有趣的细节:用于 /api/jq 的服务端工作线程池与实例可用内存紧密耦合。由于 Node.js 中的 WebAssembly 实例是内存密集型的,应用程序会根据内存量自动计算线程限制。例如,在具有 512 MB 内存的实例上,将恰好启动 2 个并行线程,最大队列将为 40 个任务。
如有必要,可以通过环境变量覆盖这些参数:
# Максимальное число параллельных потоков jq
JQ_POOL_MAX_THREADS=4
# Максимальный размер очереди запросов
JQ_POOL_MAX_QUEUE=80
如果队列溢出,API 会诚实地返回 HTTP 状态 429 Too Many Requests,防止服务因内存不足而崩溃。
如何在本地部署项目
如果你不想使用公共托管或在企业网络内需要自己的实例,启动只需几分钟。
你需要 Node.js 14 或更高版本以及 Docker(用于数据库)。
克隆仓库:
git clone https://github.com/jqlang/playground
cd playground
本地开发和测试最快的方法是运行现成的 Docker Compose,它会启动应用程序以及本地 PostgreSQL 实例:
docker compose up
启动后,在浏览器中打开 http://localhost:3000。
要构建无容器的生产版本,标准命令即可:
npm run build
npm run start
生产环境唯一必需的环境变量是包含 PostgreSQL 连接字符串的 DATABASE_URL。如果不需要链接生成功能,其他设置可以保持默认值。
谁会发现它有用
这个项目值得经常处理基础设施代码、Kubernetes 日志、CI/CD 流水线或复杂 REST API 的人收藏。
沙箱消除了为了检查单行过滤器语法而编写临时 bash 脚本的需要。而且只需两条命令就能启动自己的实例,这使其成为添加到开发团队内部工具包的最佳选择。
相关项目