Unofficial AppVeyor REST API Swagger Definition
This project aims to provide a
Swagger/OpenAPI definition
of the AppVeyor REST API. It is
neither supported nor endorsed by AppVeyor. Any differences between this
definition and the AppVeyor REST API are errors in this definition and users
are encouraged to report the
issue.
Documentation
The documentation generated from the Swagger definition is available in the
following formats:
Installation
The Swagger definition can be installed as an an npm
package by running:
npm install appveyor-swagger
It can then be used in Node.js projects with:
var appveyorSwagger = require('appveyor-swagger');
Test Client
There is a AppVeyor API Client in
Java which is generated
from the definition in this project and used for demonstration and testing
purposes. It is a good example of how to generate and use a client based on
this definition.
Implementation Notes
Versioning
The AppVeyor REST API does not provide any public versioning scheme that I am
aware of. Since versioning is necessary, both in the OpenAPI specification
file and in the npm package, the following versioning scheme is adopted:
- Major Version is kept at 0. This is both to signal that the API is
unstable (via semver
rules) and to allow any numbering which may be introduced by AppVeyor to compare
as later than these unnumbered releases.
- Minor Version is the REST API date as YYYYMMDD. This denotes the version
of the AppVeyor REST API being described which is easy to read and reason
about. Changes to this number may reflect incompatible changes to the API.
- Patch Version is the serial number of the OpenAPI/Swagger description for
the minor date. It resets to 0 each time the minor version is changed and
is incremented by 1 for each published version. Although it does not
represent a change in the REST API, it is likely to reflect a change in the
generated/validation API of software using the specification. Software using
this specification should expect API changes even when the patch version
changes and should not be depended upon such versions without testing.
Schema Names
The schema names used in the definition are based on the names returned in the
XML API responses, where those names are not confusing and do not conflict
with the requirements imposed by discriminator
. (The OpenAPI Spec requires
discriminator
property values match schema names).
Schema Strictness
There are many trade-offs between the schema strictness and the usability,
clarity, and flexibility of the code generated by the schema. This project
attempts to make the types as strict as possible without compromising
usability and clarity. This provides the most type safety (for strictly typed
languages) and protection against accidental API misuse. Specific choices are
described below.
With
Schema Types
The DeploymentEnvironment
, Project
, and Role
schemas each have a second
schema which defines additional properties
(DeploymentEnvironmentWithSettings
, ProjectWithConfiguration
,
RoleWithGroups
). The advantage to having separate types is both clarity in
the generated documentation and protection against misuse. For example,
trying to update a project using the Project
instead of
ProjectWithConfiguration
can be caught either at compile time or before the
request is made. The disadvantage is that since the generated With
classes
do not implement or inherit from the class/interface of their parent schemas
and do not provide copy constructors between them, using them becomes more
painful. I would appreciate feedback about this trade-off in real-world use
cases.
PUT
vs GET
Schema Types
PUT
schemas could be defined separately from the GET
types in several
cases. This would allow making most properties required
in the GET
types,
which could result in non-nullable/non-optional codegen in some languages
(although it does not in any that I'm currently aware of). The down-side is
that unless the codegen includes an easy way to translate data between these
types, doing a GET
+modify+PUT
becomes more painful than it should be. So
this has been not been done.
Polymorphism
swagger-polymorphic.yaml
attempts to provide stricter type definitions by
applying polymorphism using the
discriminator
property. Most tools provide limited or no support for this property.
Therefore, this file is mostly kept for reference and in the hopes that future
tools may be able to make use of it.
Polymorphic types are problematic for several reasons, not least of which is
the requirement that Schema name match the discriminator
property value,
which can cause collisions and require ugly names.
OAI/OpenAPI-Specification#403
There are various extensions available:
There are also plans to support oneOf
and anyOf
in OpenAPI v3.0
OAI/OpenAPI-Specification#741
along with adding a value to type map for discriminator
. This may solve the
above issues.
Shared responses
The next version of the spec includes support for version ranges using 4XX
notation
(OAI/OpenAPI-Specification#638).
There is also discussion of including a mechanism for defining default
responses in
OAI/OpenAPI-Specification#521
and
OAI/OpenAPI-Specification#563
Unfortunately, since neither of these is supported in OpenAPI v2.0, the
definition in this project contains a redundant error response definition for
error for each API path.