DEV Community

Cover image for API Drift Guard: Catch Breaking API Changes
P Gomes
P Gomes

Posted on

API Drift Guard: Catch Breaking API Changes

APIs break silently. A field gets renamed, a required parameter is added, an enum value is removed — and nothing stops it from shipping. Clients crash in production, mobile apps get stuck on the wrong version, and you're debugging a diff that should have been caught in review.

DriftGuard is an open-source tool that enforces API type safety across OpenAPI, GraphQL, and gRPC — detecting exactly what changed, whether it's breaking, and which parts of your codebase are affected.


The problem it solves

When a team ships an API change, the questions that actually matter are:

  1. Is this change breaking? Will existing clients stop working?
  2. What is affected? Which files or services call the changed endpoint?
  3. Did CI catch it? Or did it slip through code review?

Most tools answer one of these. DriftGuard answers all three — for all three major API schema formats.


How it works

Given two versions of a schema, DriftGuard classifies every change as breaking, non-breaking, or informational, then optionally scans your source code to surface the call sites that are affected.

drift-guard compare openapi --base old.yaml --head new.yaml

// response
BREAKING    DELETE /users/{id}
BREAKING    POST /orders — required field `payment_method` added
NON-BREAKING GET /products — description updated
Enter fullscreen mode Exit fullscreen mode

The same command works for GraphQL:

drift-guard compare graphql --base old.graphql --head new.graphql
Enter fullscreen mode Exit fullscreen mode

And for gRPC Protobuf:

drift-guard compare grpc --base old.proto --head new.proto
Enter fullscreen mode Exit fullscreen mode

Impact analysis — which code calls what changed

The diff tells you what changed. Impact analysis tells you where it matters:

drift-guard impact --schema new.yaml --source ./src

// response
BREAKING  DELETE /users/{id}
  src/services/user.service.ts:42  deleteUser()
  src/controllers/admin.controller.ts:18  removeAccount()
Enter fullscreen mode Exit fullscreen mode

This scans your source files for references to changed endpoints and maps each breaking change to the exact file and line number. It works across OpenAPI, GraphQL, and gRPC.

Severity rules

Not every change is equally dangerous. DriftGuard uses a built-in ruleset to classify each type of change:

// **Change**                             **Severity**
Remove an endpoint / field / type     Breaking
Add a required parameter              Breaking
Change a field type                   Breaking
Rename an enum value                      Breaking
Add an optional field                     Non-breaking
Add a new endpoint                    Non-breaking
Update documentation                      Informational
Enter fullscreen mode Exit fullscreen mode

The full ruleset covers all three schema types — OpenAPI, GraphQL, and gRPC severity rules are documented here.

CI integration — one step

The GitHub Action installs in a single step:

- uses: pgomes13/drift-guard-engine@v1
  with:
    format: github
    fail-on-breaking: true
Enter fullscreen mode Exit fullscreen mode

On every pull request, DriftGuard:

Detects your API framework (NestJS, Express, Fastify, Gin, Echo, etc.)
Generates the current schema from your running code
Diffs it against the base branch schema
Posts a structured comment to the PR
Fails the check if breaking changes are present
A PR with breaking changes looks like this in GitHub:


❌ 2 breaking changes detected

BREAKING  POST /orders — required field `payment_method` added
BREAKING  GET /users/{id}/profile — field `email` removed
The fail-on-breaking: true flag blocks the merge until the changes are either reverted or the PR author explicitly acknowledges them.
Enter fullscreen mode Exit fullscreen mode

Multi-service / microservices

In a multi-service environment, you often need to notify consumer services when a provider API changes. DriftGuard has a broadcast pattern for this:

Provider workflow — runs on the service that owns the API:

- uses: pgomes13/drift-guard-engine@v1
  with:
    mode: upload-diff        # stores the diff as an artifact
    notify-consumers: true   # triggers downstream checks
    notify-token: ${{ secrets.NOTIFY_TOKEN }}
Enter fullscreen mode Exit fullscreen mode

Consumer workflow — runs on services that call the provider:

on:
  repository_dispatch:
    types: [api-drift-detected]

- uses: pgomes13/drift-guard-engine@v1
  with:
    mode: impact-check       # checks if this service is affected
    source: ./src
Enter fullscreen mode Exit fullscreen mode

When the provider ships a breaking change, DriftGuard opens a PR (or issue) in every consumer repo that references the changed endpoints — before anything reaches production.

Output formats

Four output formats are supported depending on where you're running:

**Format**       **Use case**
text         Terminal / local dev
json         Machine-readable pipelines
markdown.    Documentation, wikis
github       GitHub PR comments
Enter fullscreen mode Exit fullscreen mode
drift-guard compare openapi --base old.yaml --head new.yaml --format json

{
  "breaking": [
    { "type": "endpoint_removed", "path": "DELETE /users/{id}", "severity": "breaking" }
  ],
  "non_breaking": [],
  "total": 1
}
Enter fullscreen mode Exit fullscreen mode

SDK support — Go and Node.js

For programmatic use, DriftGuard ships as both a Go package and an npm package.

Go:

import "github.com/pgomes13/drift-guard-engine/pkg/compare"

result, err := compare.OpenAPI(oldSpec, newSpec)
for _, change := range result.Breaking {
    fmt.Println(change.Path, change.Type)
}
Enter fullscreen mode Exit fullscreen mode

Node.js / TypeScript:

import { compareOpenAPI } from "@pgomes13/drift-guard";

const result = await compareOpenAPI(oldSpec, newSpec);
result.breaking.forEach(c => console.log(c.path, c.type));
Both packages expose the same diff and impact analysis APIs with full TypeScript types.
Enter fullscreen mode Exit fullscreen mode

Playground

There's an interactive playground where you can paste two schema versions side-by-side and see the diff and impact analysis live — no install required. Supports OpenAPI, GraphQL, and gRPC.

Installation

Homebrew

brew install pgomes13/tap/drift-guard
Enter fullscreen mode Exit fullscreen mode

npm

npm install -g @pgomes13/drift-guard
Enter fullscreen mode Exit fullscreen mode

Go

go install github.com/pgomes13/drift-guard-engine/cmd/drift-guard@latest
Enter fullscreen mode Exit fullscreen mode

Why this matters

API changes are inevitable. The question is whether you find out about breaking changes before or after clients are affected. DriftGuard moves that signal into the PR — where it's cheap to fix — rather than production, where it isn't.

Full documentation, severity rules, and integration guides at: pgomes13.github.io/drift-guard-engine

Source: github.com/pgomes13/drift-guard-engine

Top comments (0)