一直被错误设计的 HTTP API 参数校验模式

传统 Web framework 或者 HTTP API framework 对于接口参数校验的模式通常如下:

  1. 为每个参数绑定一个 Validator 定义
  2. 调用 Validation 对所有参数进行校验
  3. 如果验证失败则返回客户端一个错误列表,包含每一个验证失败的参数以及失败原因

但上述模式是一种错误的设计,是一种职责错位。接口调用本身隐含着契约,应该由调用者负责遵守契约,被调用者负责拒绝违反契约的调用。而不是被调用者逐项校验参数、聚合结果并返回一份错误列表。对于违反调用契约的参数,接口应当尽早失败(fail-fast),直接拒绝调用并返回 ContractViolation 错误。换句话说,接口不负责用户表单验证。如有类似需求,应该另外设计一个专用的用户表单验证接口。

以网页应用为例,在调用后端接口前,前端代码应该保证调用参数符合契约定义,而不应该依赖后端返回的错误消息列表来纠正请求参数。这种错误消息列表本质上是面向人类用户阅读的,仅在验证用户输入时才有意义。因此,应该将验证用户输入的功能从业务接口中剥离。用户输入的验证逻辑可以完全集成在前端代码里,也可以单独设计一个针对用户输入内容的验证接口。

当然,这一切的前提是接口契约必须有明确、规范且可供调用方遵循的文档定义。

……

    如何在 Coding Agent 中使用 agent-browser
    本文涉及的问题是因为我的环境非主流引起的。按照官方文档安装使用不存在以下问题。

    关于 agent-browser 工具,可以先看看 AI 是如何介绍的:

    agent-browser 是一个面向 AI Agent 的浏览器自动化 CLI 工具,让大模型能够像人一样操作网页:打开页面、读取内容、点击按钮、填写表单、截图、处理登录状态等。

    不像传统 Playwright/Selenium 经常需要解析庞大的 DOM,它通过 snapshot 输出精简的无障碍树,并给元素分配引用,例如 @e1@e2,Agent 可以直接操作这些引用,减少上下文消耗。

    简单地说,就是一个操作浏览器访问网站的工具,最大的特点是节省 Token。

    ……

    VirtualBox VBoxUSBMon 和 usbipd-win 冲突

    今日通过 WinGet 升级 VirtualBox 7.2.14,安装失败。退回安装老版本 7.2.12,依旧安装失败。查看安装日志,发现问题出在启动 VBoxUSBMon 服务失败:

    VBoxInstallHelper: *** Error: Starting service 'VBoxUSBMon' failed: VERR_UNRESOLVED_ERROR (1058 / 0x422)
    MSI (s) (D4!70) [09:54:46:712]: Closing MSIHANDLE (1754) of type 790531 for thread 8304
    VBoxInstallHelper: ServiceControl: Handling done (rc=VERR_UNRESOLVED_ERROR)
    MSI (s) (D4:8C) [09:54:46:713]: Closing MSIHANDLE (1744) of type 790536 for thread 19532
    CustomAction ca_VBoxUSBMonDrvStart returned actual error code 1603 (note this may not be 100% accurate if translation happened inside sandbox)

    联想到前几天安装 usbipd-win,当 VirtualBox 虚拟机正在运行时,会安装失败,必须关闭虚拟机才能安装。我就怀疑这俩家伙有冲突。果然,在卸载 usbipd-win 后,重新安装 VirtualBox 成功。

    ……

    mise 升级又出幺蛾子
    原来是 mise 官方不再支持第三方编译的二进制文件。这种 Breaking Change 应该在升级时有明确提示,这也太粗糙了。

    使用 mise 管理 Windows 平台的开发工具已经有一阵子了。这几天突然发现 mise 管理的 PHP 失效了。现象是找不到 php 命令、重新安装 PHP 失败。疑为某次 mise 版本升级导致的问题。

    ……

    曾立在上海市中心的女性旌表牌坊

    在如今车水马龙的上海市中心人民广场,曾经有一座屹立了 200 多年的贞洁牌坊。它旌表的对象是一位名为「陆肇嘉之妻赵氏」的女性。

    拍摄于 1939 年

    拍摄于 1939 年

    ……

    Nim 编译器的古怪问题

    Nim 是一门高度灵活的编程语言,其代码具有很强的多态与组合能力,尤其在使用 macro 时,语义往往需要在编译期展开后才能最终确定。这种高自由度的设计在增强抽象能力的同时,也引入了显著的语义不确定性,使得程序行为更依赖上下文推导与编译期分析。

    最近碰到一个令人迷惑的 Nim 编译器问题。在某个模块中,我定义了如下的宏,用于提供对 config 对象的读写封装:

    ……

    给 C 盘腾地方

    Windows 软件默认都爱往系统分区里拉屎(存放数据),很容易导致 C 盘红温(磁盘空间耗尽)。目前 C 盘是一整块独立的固态硬盘,无法再通过合并分区来扩容,只能把一些体积较大的数据迁移到数据盘。

    ……

    VSCode 远程连接 Vagrant 虚拟机开发环境

    VSCode 远程连接 Vagrant 虚拟机和连接 WSL 开发环境大同小异。只是要注意一个小问题:本地可能存在多个 Vagrant 开发环境共享同一个 IP 端口,即 127.0.0.1:2222,这会导致 SSH 连接时报安全警告。在 %USERPROFILE%\.ssh\config 文件里添加如下配置:

    Host Vagrant
      HostName 127.0.0.1
      Port 2222
      User vagrant
      StrictHostKeyChecking no
      UserKnownHostsFile NUL
    %USERPROFILE%\.ssh\config

    ……

    RegGetValueW 返回字符串数据大小不一致

    Windows API RegGetValueW 函数的原型如下:

    c++LSTATUS RegGetValueW(
      [in]                HKEY    hkey,
      [in, optional]      LPCWSTR lpSubKey,
      [in, optional]      LPCWSTR lpValue,
      [in, optional]      DWORD   dwFlags,
      [out, optional]     LPDWORD pdwType,
      [out, optional]     PVOID   pvData,
      [in, out, optional] LPDWORD pcbData
    );

    使用该 API 获取字符串值时,是否传递 pvData 参数会影响 pcbData 输出的值大小。

    ……

    无地自容:被“放逐”的上海人

    中共建国后,上海也经历过一次「清除低端人口」,也就是所谓的「游民改造运动」。当然,作为先行服的苏联,也在「慈父」斯大林的领导下搞过类似的运动。

    原文链接:无地自容:被 “ 放逐 ” 的上海人

    1949年,上海解放后,上海军事管制委员会开始改造上海,进行“游民改造运动”,并将游民遣送出上海。其中,12043人被遣送到苏北农场垦荒。这群人,苏北上海两处不落边,上海是他们青春时回不去的故乡,苏北是他们生活一辈子的地方。

    ……