API lifecycle & breaking changes
Because every DaloyJS endpoint is a single source of truth, the framework can answer two questions that usually need extra tooling: "how do I tell consumers an endpoint is going away?" and "did this change break my published API?" The first is solved with a route-level deprecation lifecycle; the second with an OpenAPI diff you can run in CI.
Deprecating a route
Set deprecated: true on a route to mark it in the OpenAPI document (the operation gets deprecated: true) and to emit an RFC 8594 Deprecation: true response header on every response from that route.
Scheduling a sunset date
Add a sunset date to announce when the route will be removed. It accepts an ISO-8601 string, any string new Date(...) can parse, or a Date. A route with a sunsetis implicitly deprecated, so you don't need to set both.
The Sunset value is normalized to an IMF-fixdate (HTTP date) once, at app.route(...) registration time, so a typo fails fast instead of silently shipping a malformed header. The OpenAPI operation also carries the normalized value as an x-sunset vendor extension. If your handler sets its own Deprecation or Sunset header, the framework never overwrites it.
Detecting breaking changes
diffOpenAPI(baseline, current) compares two OpenAPI 3.x documents and classifies every difference as breaking (a consumer relying on the baseline could now fail) or non-breaking (additive or informational). It is pure and dependency-free, so it runs anywhere you can read two JSON files.
The diff flags these as breaking:
- a path or operation (HTTP method) present in the baseline is removed;
- a documented response status code is removed from an operation;
- a new
requiredparameter is added to an existing operation; - an existing optional parameter becomes
required; - an operation's request body becomes required when it was not.
New paths, operations, response codes, and optional parameters, parameter removals, a newly deprecated operation, and an info.version bump are all reported as non-breaking.
The daloy diff CLI
The same engine ships as a CLI command so you can gate any two spec files without writing code. It prints the classified changes and exits 1 when a breaking change is found.
Wiring it into CI
Commit your published spec as a baseline (e.g. generated/openapi.baseline.json) and run the verify:breaking-changes gate. It compares the baseline against the freshly generated generated/openapi.json and fails the build on any breaking change. When no baseline exists yet the gate is a no-op, so you can adopt it incrementally.
See also OpenAPI generation for how the spec is produced and typed clients for how consumers pick up the contract.