Open kylef opened 5 years ago
I was thinking we could introduce a concept of "Server" into API Elements which is similiar to OpenAPI 3. A server could contain a href, and optionally hrefVariables. The href is a URI template (template href). For example a simple OAS3 server would map to a server element:
element: server
meta:
description: Production
attributes:
href: https://example.com/
Templated variables may look as follows:
element: server
attributes:
href: {scheme}://example.com/
hrefVariables:
element: object
content:
- element: member
content:
key: scheme
value:
element: enum
attributes:
enumerations:
- http
- https
A server MAY be inside a resource, or inside an API Category. The API Category may contain a "servers" category to group all available servers.
Tools such as API Documentation, API Consoles SHOULD make use of this information. Tools like API Gateways MAY utilise this information.
It should be possible to supply the server information at run-time to tooling, for example a console or documentation renderer should allow me to inject certain server information. The use-case is that it can inject mock-servers, or other tooling for example a configured API Gateway can populate server information to documentation renderer.
API Blueprint doesn't contain deployment information and thus does not emit any server elements.
NOTE, some have defined semantics for HOST
as a metadata in API Blueprint. This will stay as-is, this is NOT a feature of API Blueprint and we want to keep the seperation of deployment information out of the API Blueprint language. It will not be mapped to servers object. HOST
is NOT a feature of API Blueprint.
The schemes
, host
, basePath
is mapped into a server object similiar to the following:
element: server
attributes:
href: {scheme}://{host}/{basePath}
hrefVariables:
element: object
content:
- element: member
content:
key: scheme
- element: member
content:
key: host
- element: member
content:
key: basePath
As some of these fields are optional in Swagger 2, they may not have a value. schemes
will be mapped to either a fixed value or a enumeration of values. Similiary host
and basePath
will be mapped to variables in the server object.
There is direct mapping between OAS 'Server Object' and server API Element.
Following some discussions in OpenAPI, there is some consensus that servers
is perhaps a poor name (https://open-api.slack.com/archives/C1137F8HF/p1559929905003800), and hosts
, backends
or similiar may be a better fit.
What about ability set uri templates part in depencies on type of enviroment eg.
@klokane I think this can be solved with 'One Of', and enum, for example the MSON-pseudo code, the hrefVariables can be represented using selection:
I think you can imagine how that could be reproduced in the above element structure (didn't want to write extend/select API Elements by hand).
There can also simpler variant with enum, providing it is only one value that is changed:
element: server
attributes:
href: https://{environment}/
hrefVariables:
element: object
content:
- element: member
content:
key: environment
value:
type: enum
attributes:
enumerations:
- element: string
meta:
title:
element: string
content: Development
content: dev.example.com
- element: string
meta:
title:
element: string
content: Production
content: example.com
Nice idea, maybe we should introduce standardized way howto place this into Blueprint to allow tooling work with. In relation to enviroment variables, it can be good idea for dredd (cc @honzajavorek)
There's a proof of concept implementation for OpenAPI 2 parser at https://github.com/apiaryio/api-elements.js/commit/50dc4947c1e51a60108f4deef94e3dfd442236da.
I had some discussions with @tjanc who proposed we should re-use the "resource" element because it already contains href
and hrefVariables
. Semantically, a server IS a resource. Therefore we can use the existing Resource Element instead of introducing a new element. To be able to differentiate the resource element from other resources, we can add an additional classifier of host
to represent it is a host.
element: resource
meta:
classes:
- host
attributes:
href: {scheme}://example.com/
hrefVariables:
element: hrefVariables
content:
- element: member
content:
key: scheme
value:
element: enum
attributes:
enumerations:
- http
- https
In terms of a category of these types of resources, we can have a hosts
category which looks as follows:
element: category
meta:
classes:
- hosts
content:
- element: resource
meta:
classes:
- host
attributes:
href: {scheme}://example.com/
hrefVariables:
element: hrefVariables
content:
- element: member
content:
key: scheme
value:
element: enum
attributes:
enumerations:
- http
- https
OpenAPI 3 also supports attaching a set of "Server Object"s to a resource (Path Item Object) or a transition (Operation Object). As such, in this case we can introduce a hosts
attribute to "Resource Element" and "Transition Element" as follows:
element: resource
attributes:
href: /foo
hosts:
element: category
content:
- element: resource
meta:
classes:
- host
attributes:
href: {scheme}://example.com/
hrefVariables:
element: hrefVariables
content:
- element: member
content:
key: scheme
value:
element: enum
attributes:
enumerations:
- http
- https
The existing API Elements referencing is also possible, thus:
element: resource
meta:
id:
element: string
content: productionServer
can be referenced:
element: productionServer
To summarise, API Element may offer the following:
host
hosts
hosts
on Resource
and Transition
elements to contain Category of hosts.
This is an issue to propose / discuss how we should expose information on where a particular API is deployed.
Current Support
API Blueprint
The API Blueprint does not include any support for describing the deployment information. API Blueprint does allow metadata at the top of an API Blueprint. Many tools use the metadata
HOST
which can be a URL to where the API may be deployed.This is translated to
metadata
attribute for an API Category in API Elements:Swagger 2
Swagger 2 provides support for deployment information with
schemes
(array)host
andbasePath
. Our adapter takes the first schema and host and places that in the same metadata section as API Blueprint so that the value is in a format that is already used by tooling and didn't require tooling updates.The above Swagger 2 structure would result in a
HOST
metadata ofhttps://example.com
andbasePath
would be prepended into every href found in the parse result which perhaps isn't the most ideal way to handle it. The problem is that thebasePath
may be supplied without ahost
and thus couldn't be exposed asHOST
metadata.OpenAPI 3
In OpenAPI 3 a lot of server information including server variables may be described. See https://github.com/OAI/OpenAPI-Specification/blob/50c152549263cda0f05608d514ba78546b390d0e/versions/3.0.0.md#server-object or more details.