User:DKinzler (WMF)/API Life Cycle

This document provides guidelines for the URL structure of MediaWiki and Wikimedia REST APIs, with a special focus on compatibility and life cycle management.

URL Structure
Wikimedia REST endpoints can be either per-domain, or central. Contral endpoints are access on api.wikimedia.org. All central endpoints are Wikimedia specific. Per-domain endpoints may be Wikimedia specific or portable (that is, defined by a component that can easily be installed and run by a third party).

All public REST endpoints should follow one of two URL patterns:


 * (central)
 * (per domain)

[TBD: should we distinguish URLs for portable from non-portable APIs somehow?]

The  part of the endpoint URL ideally identifies the domain of the API. However, it is more important that reflect organizational reality: all endpoints under a given component should be owned by a single team, just like all code in a software component should be owned by a single team. If two teams are running endpoints that are conceptually similar, they should still use different  prefixes. This may even mean using the team name as the component prefix.

The reason for insisting that component prefixes align with team boundaries is that components are units of versioning, and teams must have autonomy over the life cycle of endpoints they run.

MediaWiki extensions and stand-alone backend services should generally have a separate  prefix. They may share a prefix with another service or extension only if both are maintained by the same team.

If we end up having many ugly sounding, non-obvious component names, this indicates that something is wrong with the team structure. In that case, both the teams and the APIs should be re-structured, using the mechanisms described in the sections on Versioning and Deprecation.

Note that central endpoints should not include a  parameter in the path. If the resourced accessed by an API is specific to a site, it should be accessed using the domain of that site, not using an endpoint on.

Versioning
The  part of the URL is composed of the following parts:


 * A prefix, which is  for stable public endpoints. Other prefix letters such as   or   or   may be used for unstable endpoints and release preparation. All endpoints using the   prefix are subject to the deprecation policy, and use semantic versioning, as far as it is applicable to APIs. Endpoints using a prefix other than   are encouraged to use the same versioning mechanism, but do not have to.
 * The major version number. Per the principle of semantic versioning, no breaking changes are done within a major version, but different major versions are mutually incompatible.
 * A minor version number. Per the principle of semantic versioning, the minor version is inclremented every time an addition is made to the API, so that higher minor versions remain compatible with clients expecting a lower minor version, but not vice versa. Including the minor version number in the API versioning allows clients that interact with multiple installations of mediawiki to rely on certain features being available in the API.

So for instance, the part of the URL might be something like   or. Note that there is no third numeric component used wit the  prefix, since bug fix releases are not relevant for APIs.

The current stable implementation of an endpoint must be accessible using any URL that has the correct major version number and the current minor version number, or any lower version number: if the current stable version is 2.17, then requests for version,  , and   should all be handled by the current code, while   and   should use a different handler, and   should fail because it is unknown.

If no minor version is given by the client, a redirect (code 308) should be triggered to the corresponding URL with the current minor version number - in the above example,  would redirect to. This provides a mechanism for discovering the latest version number. Clients are however discuraged from using the major-version-only form of the URL. They should specify the the full version number that identifies the behvaior they expect. When in doubt, client should start by specifying minor version 0, and change the required minor version when they need features that were introduced later.

Documentation for an endpoint should generally use URLs that include the version that introduced the endpoint.

Deprecation
After releasing a new major version of an API, we may want to deprecate the old version, to reduce the maintenance and administration burden. There are several aspects to consider:

Clients should be notified of the deprecation, ideally in advance. This should be done using an appropriate HTTP header. [TBD: How exactly is still not quite clear. Options include]:


 * The proposed Deprecation and Sunset headers, see https://datatracker.ietf.org/doc/draft-ietf-httpapi-deprecation-header/ and https://datatracker.ietf.org/doc/html/draft-wilde-sunset-header-11.
 * The obsolete Warning header, code 299, see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Warning.
 * A custom header, such as

Deprecated endpoints should remain functional for some time after deprecation. Ideally, the old endpoint should issue a redirect (with status code ) to the new equivalent endpoint. This is particularly useful when the endpoint was merely migrated to another component (more on that below). The redirect response must contain a header indicating deprecation, and should contain additional information about the derpecation in the response body.

If it is not possible to construct a redirect that will produce semantically equivalent behavior, the old handler code should be kept in place. If code is shared with the new handler, care must be taken to ensure that changes to that shared code do not impact the behavior of the old endpoint. The best way to achieve this is to have a comprehensive test suite in place that ensures that the deprecated endpoint is still behaving to spec.

A special case of deprecation is the migration of an endpoint. In that case, the deprecation is not due to the release of a new major version, but to the relocation of the endpoint to a new URL, without a change in behavior. This would be the case when re-drawing component boundaries (e.g. when teams are being restructured).

Relocating an endpoint to a different component requires a minor version bump of the target component. The version number of the old component is irrelevant. For instance, if we want to migrate an endpoint currently located at  to the component , the resulting endpoint URL would be.

Removal
metrics and UAs

flickering lights

Releases
beta and rcs

Unstable Endpoints
internal/private/unstable vs experimental

dev only (hidden in production)

Compatibility
adding parameters

adding response body fields

removing response body fields

removing parameter support

changing allowed values

adding required request body fields

Migration
Per the writing of this document in early 2023, Wikimedia sites are exposing public REST endpoints in three ways:


 * as  for endpoints defined by MediaWiki core or extensions
 * as  for endpoints served from RESTbase
 * as  for endpoints using the new API gateway

Most of these endpoints should be migrated to using the URL structure defined in this document.

Migrating these endpoints should follow the process described for deprecation in general. In particular, the old URLs should be responsing with redirects (status ) to the new location of the endpoints.

Routing Architecture
Routing in LB


 * handling of /rest.php
 * handling of /api/
 * redirects?
 * third party wikis?

Routing in Gateway


 * routing of per-domain apis
 * routing to rest.php?
 * routing based on major version
 * different routing for individual endpoints?
 * migration redirects?

MW


 * version routing + checking
 * migration redirects

node


 * version routing + checking
 * migration redirects