dwgx@blog:~$dwgx
> cd ../posts

imnot: 一份 YAML 起个有状态 mock server

// created

imnot 是个有状态的 API mock server: 一份 YAML 描述外部接口, imnot start 就起一个能跑的 mock, 加接口不用改代码。Python 写, 底子是 FastAPI, 会话状态落 SQLite, 够轻。它不是我写的, 原作者 edu2105, 我 fork 下来魔改研究。

它解决的是集成测试里外部 API 的麻烦: 第三方支付、OAuth 换 token、异步提交轮询取结果、webhook 回调, 全是坑。CI 里没法真打人家沙箱, 慢、不稳、还限流。以前要么写一堆 mock 代码, 要么摆个笨重 GUI, imnot 用 YAML 声明就完事。

最有意思的是它把“有状态”建进 YAML, 不散在脚本里。几种 pattern:

  • oauth client-credentials 换 token, 返回静态 JWT
  • static 永远吐 YAML 里写死那段 JSON
  • fetch 同步 GET, 把之前存的 payload 吐回来
  • async N 步异步流, 从 submit 到查状态到取结果, 步数和方法都在 YAML 配
  • push 先立刻返回, 再主动往回调 URL 发 payload, 模拟对方回调你 webhook

payload 分全局和会话两层。并发跑测试靠一个 X-Imnot-Session 头隔离, 每个 test 拿自己那份, 互不打架, 比一份 fixture 大家共用干净。还带常驻 admin API, 能上传 payload、热重载 YAML(POST /imnot/admin/reload), POST 段 YAML 就挂新 partner 路由, 不用重启, 也能导 Postman collection。一个进程塞容器长期跑, 正合我自托管的胃口。

fork 主要想看 imnot/engine/patterns/ 那几个 handler 怎么把 YAML 变成动态注册的 FastAPI 路由, router.py 那套工厂写法最想学。它也没藏短板: push 回调没重试, 没原生 HTTPS 得靠反代终止 TLS, 没 Web UI 只出 JSON, SQLite 不跨实例, 单节点玩具。家里机器跑测试够用。

一个坑: 运行时 HTTP 写进去的 partner 落在容器本地文件系统, Pod 一重启就没, 得自己挂持久卷到 /app/partners/app/data。这不是 bug, 它明说持久化是你自己的事。