From a2dd45ed5de698dda4b3e3d8d2d133f957fb598c Mon Sep 17 00:00:00 2001 From: Andrei Matei Date: Fri, 19 Jun 2026 10:07:57 +0100 Subject: [PATCH] feat(ipa): Enrich IPA-120 Versioning with structured metadata CLOUDP-399914 --- ipa/general/0120.mdx | 431 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 414 insertions(+), 17 deletions(-) diff --git a/ipa/general/0120.mdx b/ipa/general/0120.mdx index 7b7d7fe..63e27b8 100644 --- a/ipa/general/0120.mdx +++ b/ipa/general/0120.mdx @@ -7,26 +7,423 @@ state: adopt API producers should avoid incrementing the API version where possible, prioritizing supporting the current API version unless absolutely necessary. -This philosophy reduces exposing our clients to the friction of migrating -versions and multiple versions complicates maintenance, testing and -documentation for MongoDB. +This philosophy reduces exposing clients to the friction of migrating versions, +and multiple versions complicate maintenance, testing, and documentation. ## Guidance -- API producers **should** consider whether their changes warrant a new version - or can be made backward compatible - - API producers **should** refer to backwards compatibility - ([IPA-116](0116.mdx)) prior to versioning their API - - API producers **should not** version their API if the desired functionality - can be achieved in a backwards compatible fashion - - API producers **should** consider whether introducing a new endpoint - alongside existing, in lieu of a new version - - API producers **should** avoid versioning an API solely to rename existing - fields or paths -- API producers **may** coordinate to sunset old versions faster than the - default timeline of one-year -- API producers **must** coordinate with clients to transition to new versions - to avoid impact + + + + +An API producer **should** consider whether a change warrants a new version or +can instead be made in a backward-compatible fashion, referring to backward +compatibility ([IPA-116](0116.mdx)) before versioning the API. + + + + + +```yaml +paths: + /users/{userId}: + get: + operationId: getUser + responses: + "200": + content: + application/json: + schema: + type: object + properties: + id: + type: string + name: + type: string + email: + type: string +``` + + + Adding the optional `email` field to an existing response is additive and + backward compatible, so the change lands in the current version instead of + forcing a new one. + + + + + + +```yaml +paths: + /v2/users/{userId}: + get: + operationId: getUserV2 + responses: + "200": + content: + application/json: + schema: + type: object + properties: + id: + type: string + name: + type: string + email: + type: string +``` + + + A whole new version is spun up to carry one additive field that the current + version could already accept, splitting clients across versions for no + compatibility reason. + + + + + + + Identify the change under review and the version it targets — a new version + path/prefix, a new version-tagged operation, or a header-selected version. + + + Classify the change against IPA-116: adding optional fields, new optional + parameters, or new operations is additive; removing or renaming + fields/paths, tightening types, or changing required-ness is breaking. + + + Confirm that any change introducing a new version is one that cannot be + expressed additively in the current version. + + + Report any new version whose change is additive and could have stayed in the + current version. + + + + + + + + + +An API producer **should not** version the API when the desired functionality +can be achieved in a backward-compatible fashion. + + + + + +```yaml +paths: + /orders/{orderId}: + get: + operationId: getOrder + parameters: + - name: includeItems + in: query + required: false + schema: + type: boolean + responses: + "200": + description: An order. +``` + + + The new behavior is opt-in through an optional query parameter on the existing + operation, so the functionality ships without a version bump. + + + + + + +```yaml +paths: + /orders/{orderId}: + get: + operationId: getOrder + responses: + "200": + description: An order. + /v2/orders/{orderId}: + get: + operationId: getOrderV2 + parameters: + - name: includeItems + in: query + required: false + schema: + type: boolean + responses: + "200": + description: An order with items. +``` + + + The same opt-in behavior is delivered by duplicating the operation under a new + version, even though an optional parameter on the existing operation would + have been backward compatible. + + + + + + + For each newly introduced version, list the functionality it adds relative + to the prior version. + + + For each added capability, determine whether it could be expressed in the + current version through additive means: an optional parameter, an optional + response field, or a new operation. + + + Flag any version whose entire delta is achievable backward-compatibly in the + current version. + + + + + + + + + +An API producer **should** consider introducing a new endpoint alongside the +existing one, in lieu of a new version. + + + + + +```yaml +paths: + /projects/{projectId}/reports: + get: + operationId: listReports + /projects/{projectId}/reports/summary: + get: + operationId: getReportSummary +``` + + + The new summarized behavior is exposed as an additional endpoint next to the + existing collection, so neither the operation nor the version has to change. + + + + + + +```yaml +paths: + /projects/{projectId}/reports: + get: + operationId: listReports + /v2/projects/{projectId}/reports: + get: + operationId: listReportsV2 +``` + + + A distinct capability is delivered by re-versioning the same resource rather + than adding a sibling endpoint, which would have left existing consumers + untouched. + + + + + + + For each new version, identify the resources or operations it introduces. + + + Determine whether each new capability represents distinct functionality that + could live at its own path alongside the existing endpoints. + + + Flag versions whose additions are new capabilities that a sibling endpoint + in the current version could have carried. + + + + + + + + + +An API producer **should** avoid versioning an API solely to rename existing +fields or paths. + + + + + +```yaml +paths: + /invoices/{invoiceId}: + get: + operationId: getInvoice + responses: + "200": + content: + application/json: + schema: + type: object + properties: + total: + type: number + amount: + type: number + deprecated: true +``` + + + A clearer name is added while the old field is kept and marked deprecated, so + the rename happens without a version bump and without breaking existing + clients. + + + + + + +```yaml +paths: + /v2/invoices/{invoiceId}: + get: + operationId: getInvoiceV2 + responses: + "200": + content: + application/json: + schema: + type: object + properties: + total: + type: number +``` + + + A new version exists only to rename `amount` to `total`, which forces every + client to migrate for a purely cosmetic change. + + + + + + + For each new version, diff its fields and paths against the prior version. + + + Determine whether the only differences are renamed fields or paths with no + change in behavior, type, or semantics. + + + Flag any version whose sole change is a rename of existing fields or paths. + + + + + + + + + An API producer **may** coordinate to sunset old versions faster than the + default timeline of one year. + + + + +An API producer **must** coordinate with clients to transition to new versions +to avoid impact. + + + + + +```yaml +paths: + /v1/users/{userId}: + get: + operationId: getUserV1 + deprecated: true + responses: + "200": + headers: + Sunset: + schema: + type: string + format: date + description: A user. This version is deprecated; migrate to v2. + /v2/users/{userId}: + get: + operationId: getUserV2 + responses: + "200": + description: A user. +``` + + + The superseded version stays available, is marked `deprecated`, and advertises + a `Sunset` date, giving consumers a signalled window to move before the old + version is withdrawn. + + + + + + +```yaml +paths: + /v2/users/{userId}: + get: + operationId: getUserV2 + responses: + "200": + description: A user. +``` + + + The previous version was removed outright with no deprecation marker or sunset + signal, so consumers still on it break the moment it disappears. + + + + + + + Compare the spec against the previously published version to find any + operations or versions that were removed or replaced. + + + For each superseded version, confirm the prior version remains available + during a transition window rather than being dropped at once. + + + Confirm the superseded operations are marked `deprecated` and advertise a + sunset signal (such as a `Sunset` header or a deprecation date in the + description). + + + Inspect release notes, changelogs, or client-communication records to + confirm consumers were notified ahead of the transition. + + + Report any version transition that removes a prior version without a + deprecation period, sunset signal, and evidence of client coordination. + + + + + + + + ## Further Reading