<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>compatibility on </title>
    <link>/tags/compatibility/</link>
    <description>Recent content in compatibility on </description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en</language>
    <lastBuildDate>Sat, 25 Apr 2026 10:00:00 +0800</lastBuildDate><atom:link href="/tags/compatibility/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>API 与 event contract 兼容性保障：工具机制与正确用法</title>
      <link>/posts/api-event-contract-compatibility-qa-2026/</link>
      <pubDate>Sat, 25 Apr 2026 10:00:00 +0800</pubDate>
      
      <guid>/posts/api-event-contract-compatibility-qa-2026/</guid>
      <description>📦 本文基于的完整项目源码：meirongdev/shop
上一篇 微服务 contract 兼容性的五层防线：从 ArchUnit 到 japicmp 讨论了如何用 ArchUnit、japicmp、WireMock 和运行时 Deprecation 头构建基础安全带。本文聚焦更具体的问题：BFF 对外的 API、BFF→MS 和 MS→MS 的内部 API、以及 Kafka 事件，各自应该用什么工具保障 contract 兼容性，这些工具的工作机制是什么。
一、两类 contract，两种保障方式 Q：BFF 对外暴露的 API 和 BFF→MS、MS→MS 之间的内部 API，兼容性的保障方式应该一样吗？
在我的实践中不太一样。主要原因在于 source of truth 不同。
BFF 对外的 API（前端、移动端、三方调用方）采用的是 API-first 方式：先有 OpenAPI YAML，生产者的 controller 实现这份 YAML，消费者根据这份 YAML 生成客户端代码或手写调用。在这条链路里，YAML 就是权威来源。保障兼容性就是保障 YAML 文件本身不引入 breaking change。
BFF→MS 和 MS→MS 之间采用的是 code-first 方式：Java record 是 source of truth，没有提前写 spec，序列化层（Jackson）从 record 推导出 JSON 结构。保障兼容性就是保障 Java record 的 JSON 表现形式不引入 breaking change。</description>
    </item>
    
    <item>
      <title>微服务契约兼容性的五层防线：从 ArchUnit 到 japicmp</title>
      <link>/posts/microservice-contract-compatibility-defense-in-depth/</link>
      <pubDate>Wed, 22 Apr 2026 23:00:00 +0800</pubDate>
      
      <guid>/posts/microservice-contract-compatibility-defense-in-depth/</guid>
      <description>📦 本文基于的完整项目源码：meirongdev/shop
先说我的做法 如果你在做一组 Java 微服务，已经把 contracts 独立成 jar、每个 caller 自己写 client，你会很快遇到下一个问题：谁来阻止下一次 contracts 变更悄悄打穿所有下游？
我现在更倾向的做法是——把五层防线组合起来，单独任何一层都不太够：
ArchUnit COMPAT-01：每个 *Api 的 BASE_PATH 最好带显式版本段（/vN 或 /internal）。 ArchUnit COMPAT-02：事件契约最好容忍未知字段，并带上 schemaVersion。 ArchUnit COMPAT-03：任何 @ApiDeprecation 最好都声明 replacement。 japicmp 二进制兼容门禁：在 Maven verify 阶段对比新旧 contracts jar，binary-incompatible 变更直接 fail build。 WireMock 契约测试：consumer 侧冻结自己对契约的理解，任何反序列化漂移都暴露在单元测试阶段。 加上运行时的 ApiCompatibilityInterceptor（自动写入 X-API-Version / Deprecation / Sunset / X-API-Replacement）——这些一起构成了一个可执行的&amp;quot;契约安全带&amp;quot;。
这篇文章把 shop 项目里具体是怎么落地的写下来，也把近两年可以对照的业界参考一起贴上。
为什么只共享 contracts 还不够 上一篇 微服务契约共享的 Tradeoff 讲过——共享 @HttpExchange 接口是反模式，真正该共享的是 contracts（路径常量 + DTO）。问题是，一旦契约成了跨服务的共识，它就变成了一个隐式的耦合面：
某个 caller 在 OrderApi.</description>
    </item>
    
  </channel>
</rss>
