User:DKinzler (WMF)/API URL Guidelines
This page is currently a draft.
|
This document provides guidelines for the URLs under which APIs are exposed on Wikimedia sites. It is intended primarily for the use with REST APIs, but is designed to be applicable to other types of APIs as well.
Note that this guideline does not mandate any change to or replacement of the MediaWiki action API. See the bottom opf this page for an exmplanation of how these guidelines relate to Existing APIs.
Changes over Previous Practice
[edit]/w/rest.php
for MediaWiki /api/rest_v1
for RESTbase). Per this policy, a routing prefix comes with operational guarantees and constraints. It will often correspond to an API gateway.
By looking at the routing prefix, it should be obvious whether the APIs under it are intended for public use or not.https://api.wikimedia.org/
is the base URL of the generic cross-wiki routing prefixapi
, for use by general purpose public APIs.https://en.wikipedia.org/api/
is a URL using the generic per-wiki routing prefix/api/
, for use by general purpose public APIs.https://api.enterprise.wikimedia.org/
uses the cross-wiki prefixapi.enterprise
, indicating a high availability APIs for enterprise customers.
Possible future examples:
https://en.wikipedia.org/internal-mobile-api/
could be the base URL for APIs reserved for use by the Wikipedia app.
/api/rest_v1/page/...
provide access to wiki pages and are implemented by the content module in RESTbase.
Per this policy, component APIs are defined to be modeling conceptual domains and are expected to align with team boundaries. Versioning is shifted from the entry point to the level of individual components, to provide teams with control over the evolution of the APIs they own.- instead of
/api/rest_v1/page/...
, the page endpoints could be moved into a new content component using the path/api/content.v2/page/...
.
Guideline for Exposing New APIs
[edit]https://{wiki}/api
. If the API operates across wikis, it should use a cross-wiki routing prefix, like https://api.wikimedia.org/
. Only if the API has special operational needs or restrictions, and the team that maintains the API will maintain infrastructure desigend to meet these needs, the creation of a dedicated routing prefix may be considered.
https://{wiki}/internal-api
and https://internal-api.wikimedia.org
. Using "internal" here in the same way we use it in PHP for things that are technically accessible, but shouldn't be accessed and are not stable. -- DKinzler (WMF) (talk) 21:50, 4 July 2023 (UTC)Since the API is going to be public for use by gadgets, and it interacts with wiki pages, it will be using the per-wiki https://{wiki}/api
routing prefix.
The component will be called user-badges, because that is the domain/scope that the team is working on at the moment. The new endpoint will not be added to the (supposedly) existing user and page components, since these components are owned by different teams. Also, while there is conceptual overlap, the user-badges has a somewhat different perspective on users and user pages.
So, once it has reached maturity, the new endpoint will be exposed as https://{wiki}/api/badges.v1/barnstars/{user}
, as part of the "badges API".
Since the API is going to integrate infromation across all wikis, it will be using the cross-wiki routing prefix.
The component will be called 'glam-monitor', which is the name of the product that is going to be provided to GLAM partners. Since the API has special operational demands and the team plans to operate the infrastructure that handles it, the routing prefix (i.e.e the domain name) will be dedicated to the component.
So, once it has reached maturity, the new API will use the URL https://glam-monitor-api.wikimedia.org/v1/
, with https://glam-monitor-api.wikimedia.org/
being the routing prefix.
Norms for API URLs
[edit]Routing Prefixes
[edit]- per-wiki APIs operate on content of a specific wiki site. They use URLs of the form
https://{wiki-domain}/{prefix}/{component}/{endpoint}
. The routing prefix is part of the path, so the same routing prefix is available on each of the different wiki domains. - cross-wiki APIs operate across wikis. They use URLs of the form
https://{prefix}/{component}/{endpoint}
. The routing prefix is at least a domain name, but may also include a path prefix.
- for public per-wiki APIs, the
/api/
path prefix, as inhttps://en.wikipedia.org/api/
. - for public cross-wiki APIs, the
api.wikimedia.org
domain, as inhttps://api.wikimedia.org/
.
/api/
:
- Dedicated cross-wiki routing prefix:
https://{prefix}/{version}/{endpoint}
- Dedicated per-wiki routing prefix:
https://{wiki-domain}/{prefix}/{version}/{endpoint}
The Content Translation API uses a dedicated routing prefix (and the cross-wiki URL pattern):
https://cxserver.wikimedia.org/v2/page/{sourcelanguage}/{targetlanguage}/{title}
.
The routing prefix as well as the component is cxserver
, the version is v2
. The page
part ofthe URL identifies the endpoint and is followed by the resource path, {sourcelanguage}/{targetlanguage}/{title}
.
However, we have historically been using the term "internal" for both, which causes confusion.
Calling such APIs "non-public" would be consfuing as well, since they are accessible from outside the WMF network, though they are not intended for public use. The term "unstable" is generally used for interfaces that are not yet stable, but intended to become so....
We could also use the term "restricted". Or perhaps "bespoke", since such APIs tend to be bound to a specific client.internal-api
, unless there is a specific reason to expose it through additional or different prefixes. /api/
) are typically portable, meaning that they are defined by a component that can easily be installed and run by a third party. Other APIs are typically WMF-specific."api"
, to avoid collisions with component names as well as paths and subdomains used for other purposes. See also Constraints on Names below.https://en.wikipedia.org/api/
withhttps://en.wikipedia.org/api/foo/
.https://api.wikimedia.org/
withhttps://api.wikimedia.org/foo/
The following routing prefixes are not in conflict with each other:
https://api.wikimedia.org/
withhttps://foo.api.wikimedia.org/
https://api.wikimedia.org/
withhttps://foo-api.wikimedia.org/
https://api.wikimedia.org/
withhttps://api.foo.wikimedia.org/
https://en.wikipedia.org/api/
withhttps://en.wikipedia.org/api.foo/
.https://en.wikipedia.org/api/
withhttps://en.wikipedia.org/foo/api/
.
https://api.wikimedia.org/api/
. Or say that they are indeed in conflict, but we just live with it for now. -- DKinzler (WMF) (talk)Component APIs
[edit]{component}
part of the URL represents a logical grouping of endpoints which together consitute the API of a functional component.'''{base-name}.{version}'''
. Using other separators like slash or dash or underscore is acceptable but discouraged. Examples include {name}core/v1{version}
and rest_v1
. See also Constraints on Names below.
"-api"
. This avoids collisions with routing prefixes. See also Constraints on Names below.api.{name}.wikimedia.org
? It's not as nice when reading out aloud, but matches the way subdomains are typically used. -- DKinzler (WMF) (talk) 12:43, 11 July 2023 (UTC)/foo/bar/
with/foo/
The following components are not in conflict with each other:
/foo/
with/bar/foo/
/foo/bar/
with/foo/bla/
/foo-bar/
with/foo/
Endpoint Paths
[edit]{prefix}/{component.version}/{endpoint}/{resource}
. See the REST Resource Guidelines for details.Constraints on Names
[edit]namechar = ALPHA / DIGIT
separator = "/" / "-" / "." / "_"
name = 1*namechar *( separator namechar )
w
: used as MediaWiki's script path.wiki
: used as MediaWiki's article path.test
: reserved for testing. [TBD]debug
: reserved for testing. [TBD]status
: reserved for operational use. [TBD]wmf
: generic prefx/suffix for restricted (private) APIs [TBD]api
: generic prefx/suffix for public APIs
Existing APIs
[edit]This section explains how this guideline relates to pre-existing API.
RESTbase REST API (rest_v1)
[edit]https://{wiki}/api/rest_v1/
, where rest_v1
acts as a component name shared by all endpoints exposed by RESTbase.https://en.wikipedia.org/api/rest_v1/page/html/Earth
Here, the component is page
and the resource path is html/Earth
.
/api/content.v1/page/html/Earth
would allow for more autonomy, since the endpoints under the content
component could be evolved independently of other endpoints.MediaWiki REST API (rest.php)
[edit]https://{wiki}/w/rest.php/
. Most endpoints are currently exposed under https://{wiki}/w/rest.php/v1/
, where the /v1/
acts as a component name./w/rest.php/
behave like a dedicated prefix. This has been making it difficult to update APIs, since it makes it effectively impossible to change the version number. A structure like /api/content.v1/page/html/Earth
would allow for more flexibility, since endpoints under the content
component could be evolved independently of other endpoints.MediaWiki Action API (api.php)
[edit]https://{wiki}/w/api.php
. It is an RPC style API. Individual procedures are addressed using the action
parameter.https://{wiki}/action-api/query.v2
, where query.v2
is the component (or action), would allow for more flexibility.Wikimedia API Gateway (api.wikimedia.org)
[edit]https://api.wikimedia.org/
. It serves as the default routing prefix for public cross-wiki APIs.https://api.wikimedia.org/service/lw/inference/v1/models/enwiki-articlequality:predict
This uses the default cross-wiki routing prefix, https://api.wikimedia.org/
, followed by the component name and version service/lw/inference/v1
, followed by an endpoint and resource path.
A component name that contains slashes like this may be taken to imply a hierarchy of sub-components. This kind of structure us not recommended, since it makes it harder to immediately identify the component and owner by looking at the URL.
https://internal-api.wikimedia.org/
, unless there is a specific reason to expose it through additional or different prefixes. The API Portal Wiki APIs
[edit]https://api.wikimedia.org/
prefix, which is the routing prefix for cross-domain wiki APIs, but also the domain of the portal wiki. So the pathes under the reserved prefixes /w/
, /wiki/
, and /api/
are not considered to be part of the https://api.wikimedia.org/
prefix. Instead, https://api.wikimedia.org/api/
is the default routing prefix for per-wiki APIs of the portal wiki.
https://api.wikimedia.org/core/v1/wikipedia/en/page/
is an endpoint in the cross-wiki core
API.
https://api.wikimedia.org/api/rest_v1/page/html
is an endpoint in the per-wiki API for the wiki at https://api.wikimedia.org/. It has nothing to do with the base URL of the default routing prefix, https://api.wikimedia.org/
. Rather, its base URL is https://api.wikimedia.org/api/
, using the per-wiki routing prefix /api/
.
Wikimedia Enterprise API (api.enterprise.wikimedia.org)
[edit]https://api.enterprise.wikimedia.com/v2/snapshots
. The routing prefix is api.enterprise
. This does not quite match the recommendation of the URL Guidelines: the name should be enterprise-api
.
If we were to introduce per-wiki Wikimedia Enterprise endpoints, these could then be located under a dedicated routing prefix, such as /enterprise-api/
:
Content Translation API (cxserver.wikimedia.org)
[edit]https://cxserver.wikimedia.org/v2/page/{sourcelanguage}/{targetlanguage}/{title}
This API does not quite match the recommendations of the API URL Guidelines: The prefix does not end in "-api".
Attic
[edit]{path}
part empty) SHOULD return documentation about the API it exposes.
How Others Do Versioning and Deprecation
[edit]GitHub
[edit]- No versioning in endpoint URLs, requires
X-GitHub-API-Version
header, see https://docs.github.com/en/rest/overview/api-versions?apiVersion=2022-11-28 - API spec/doc is versioned by date: https://docs.github.com/de/rest?apiVersion=2022-11-28
- Breaking changes are announced, generally only addition and removal, e.g. https://developer.github.com/changes/2020-04-15-replacing-create-installation-access-token-endpoint/
- Uses brownouts!
Amazon
[edit]- Several different APIs ("Ads API" vs "SP-API" vs "Product API" vs ...)
- Deprecation announcement: https://advertising.amazon.com/API/docs/en-us/release-notes/deprecations
- Introduces (sub)component prefixes into the URL, e.g. /campaigns/ -> sp/campaigns
- Inconsistent use of version in URL, e.g. /v2/sp/campaigns/ -> sp/campaigns and /sb/beta/campaigns -> /sb/v4/campaigns
- Spec/doc is versioned by date, e.g. https://developer-docs.amazon.com/sp-api/docs/easyship-api-v2022-03-23-use-case-guide
- Uses per-region gateways: https://advertising-api.amazon.com vs https://advertising-api-eu.amazon.com
- A zoo of APIs, e.g.
- Distance matrix (maps) at https://maps.googleapis.com/maps/api/distancematrix/
- Route directions (maps) at https://routes.googleapis.com/directions/v2:computeRoutes
- Search at https://www.googleapis.com/customsearch/v1
- Knowledge Graph at https://enterpriseknowledgegraph.googleapis.com/v1/
- Docs at https://docs.googleapis.com/v1/documents.
- Some of these are RPC APIs, not REST
- Frequent use of version numbers in the URL
- Use of component prefixes ("/maps/api/" vs "/directions/")
- Use of separate entry points (
maps.googleapis.com
vsenterpriseknowledgegraph.googleapis.com
)
Meta (Facebook)
[edit]- Multiple APIs
- Marketing API: https://graph.facebook.com/v2.2/me/adaccounts
- Graph API: https://graph.facebook.com/v2.10/{my-user-id}&access_token={access-token}
- Platform API: https://www.facebook.com/v17.0/dialog/oauth
- Major and minor version numberin URL
- Use of component prefixes (but version number comes first?)
- Mix of REST and RPC
- Supports calls without version in the URL, user preferences determine which version of the API will be used.
- Some use of subdomains for routing
- Multiple APIs, e.g.:
- "the API" https://api.twitter.com/2/tweets
- "oembed" https://publish.twitter.com/oembed
- "developer API" https://ads-api.twitter.com/6/accounts
- "enterprise" https://gnip-api.twitter.com/metrics/usage/accounts/
- Version number in the URL
- Mix of REST and RPC
- Different access levels (basic, premium, enterprise, ...)
Atlassian (Jira)
[edit]- Version number in the URL, e.g. http://localhost:8080/rest/api/2/issue/createmeta
- Stability policy https://developer.atlassian.com/platform/marketplace/atlassian-rest-api-policy/ sais: "Wherever possible, REST resources and their representations will be maintained in a backwards compatible manner."
- This doesn't prevent evolution of the API, because the API version is part of the resource URL.
- Can use "latest" as version, e.g. http://localhost:8090/jira/rest/api/latest/issue/TST-1/remotelink (really?!)
Further Reading
[edit]- Mark Massé - REST API Design Rulebook https://gist.github.com/zxdcm/