==================
OpenAPI Extensions
==================
Every Composer project starts with an `OpenAPI `_ specification file. OpenAPI is a standard, language-agnostic,
document format for describing RESTful APIs. It is from this document that both server and client code can be easily
generated using the CLI tool. This enables developers to save time on initial project creation as well as providing
consistent and well-documented APIs for others to use long after the project is deployed.
The OpenAPI specification is somewhat limited, however, and avoids describing certain details about the implementation
of a RESTful API. Details that a code generator and framework like Composer must have in order to do its job properly.
Therefore, we have extended the specification to add several new features.
`Click here for an example `_.
Datastore Objects
=================
Holds a set of datastore connection configurations. All objects defined within the ``x-datastores`` object are copied
to the service's ``config.ts`` file. Schema objects desiring to be bound to a given Datastore Object must explicitly
reference it using the ``x-datastore`` field.
**Example**
.. code-block:: yaml
:linenos:
:emphasize-lines: 2-5
components:
x-datastores:
mongodb:
type: mongodb
url: mongodb://localhost
Datastore Object
================
Holds the name and associated configuration for a particular datastore connection. All properties defined in the object
are copied to the service's ``config.ts`` file. Configuration options should conform to the
`TypeORM Connection Options `_. Desired Schema objects that are to be bound
to a given Datastore object must be explicitly referenced with the ``x-datastore`` field where the value matches
the name of the object.
**Example**
.. code-block:: yaml
:linenos:
:emphasize-lines: 3-5
components:
x-datastores:
mongodb:
type: mongodb
url: mongodb://localhost
Schema Object
=============
The following extensions apply to `Schema `_ definitions.
``x-baseClass``
~~~~~~~~~~~~~~~
**Default Value**: ``null``
The ``x-baseClass`` field is applied to a `Schema `_
to identify the base class behavior that the generated Schema class will inherit. There are three possible values
presently supported by Composer.
**Possible Values**:
* ``BaseMongoEntity`` - Provides base behavior for all Schema classes that will be stored in a collection of a MongoDB database.
* ``BaseSQLEntity`` - Provides base behavior for all Schema classes that will be stored in a SQL database.
**Example**
.. code-block:: yaml
:linenos:
:emphasize-lines: 5
components:
schemas:
Order:
type: "object"
x-baseClass: BaseMongoEntity
x-datastore: mongodb
``x-datastore``
~~~~~~~~~~~~~~~
**Default Value**: ``null``
The ``x-datastore`` field is applied to a `Schema `_ to identify
which database connection the schema will be bound to. The name of the database connection must match a defined
Datastore Object.
**Example**
.. code-block:: yaml
:linenos:
:emphasize-lines: 6
components:
schemas:
Order:
type: "object"
x-baseClass: BaseMongoEntity
x-datastore: mongodb
``x-ignore``
~~~~~~~~~~~~
**Default Value**: ``false``
The ``x-ignore`` field is applied to a `Schema `_ Property to
indicate that it should be ignored from code generation.
**Example**
.. code-block:: yaml
:linenos:
:emphasize-lines: 5
components:
schemas:
Order:
type: "object"
x-ignore: true
Schema Properties
=================
The following extensions have been added to `Schema Object `_
Property definitions.
``x-identifier``
~~~~~~~~~~~~~~~~
**Default Value**: ``false``
The ``x-identifier`` field is applied to a `Schema `_ Property to
indicate that the field is a unique identifier within the database and should be indexed and must be unique.
**Example**
.. code-block:: yaml
:linenos:
:emphasize-lines: 10
components:
schemas:
Order:
type: "object"
x-baseClass: BaseMongoEntity
x-datastore: mongodb
properties:
name:
type: "string"
x-identifier: true
x-unique: true
nullable: false
``x-unique``
~~~~~~~~~~~~
**Default Value**: ``false``
The ``x-unique`` field is applied to a `Schema `_ Property to
indicate that the field is a unique identifier within the database and must be unique.
**Example**
.. code-block:: yaml
:linenos:
:emphasize-lines: 11
components:
schemas:
Order:
type: "object"
x-baseClass: BaseMongoEntity
x-datastore: mongodb
properties:
name:
type: "string"
x-identifier: true
x-unique: true
nullable: false
Path Item Object
================
The following extensions apply to `Path Item Object `_ definitions.
``x-name``
~~~~~~~~~~
**Default Value**: ``null``
The ``x-name`` field is applied to a `Path Item Object `_. It
defines the unique name of the path item and the name of the generated code route handler class. This field is
superseded by the ``x-schema`` field.
**Example**
.. code-block:: yaml
:linenos:
:emphasize-lines: 3
paths:
/user/login:
x-name: Auth
get:
description: Authenticates the user using HTTP Basic and returns a JSON Web Token access token to be used with future API requests.
x-name: login
responses:
"200":
description: The JSON Web Token to be used for all future requests.
content:
application/json:
schema:
$ref: "#/components/schemas/authToken"
**Generated Code**
.. code-block:: typescript
:linenos:
:emphasize-lines: 6-7
/**
* Handles all REST API requests for the endpoint `/user/login`.
*
* @author
*/
@Route("/user/login")
class AuthRoute {
@Config
protected config: any;
@Logger
protected logger: any;
/**
* Initializes a new instance with the specified defaults.
*/
constructor() {
}
...
}
``x-schema``
~~~~~~~~~~~~
**Default Value**: ``null``
The ``x-schema`` field is applied to a `Path Item Object `_. It
defines the Schema that the path item is bound to. This supersedes the ``x-name`` field.
**Example**
.. code-block:: yaml
:linenos:
:emphasize-lines: 3
paths:
/pet:
x-schema: Pet
get:
description: "Multiple Pet objects"
x-name: "find"
responses:
"200":
description: A list of Pet objects.
content:
application/json:
schema:
type: "array"
items:
$ref: "#/components/schemas/Pet"
**Generated Code**
.. code-block:: typescript
:linenos:
:emphasize-lines: 6-8, 14-15
/**
* Handles all REST API requests for the endpoint `/pet`.
*
* @author
*/
@Model(Pet)
@Route("/pet")
class PetRoute extends ModelRoute {
@Config
protected config: any;
@Logger
protected logger: any;
@MongoRepository(Pet)
protected repo?: Repo;
/**
* Initializes a new instance with the specified defaults.
*/
constructor() {
super();
}
...
}
Operation Object
================
The following extensions apply to `Operation Object `_ definitions.
``x-after``
~~~~~~~~~~~
**Default Value**: ``[]``
The ``x-after`` field is applied to a `Operation Object `_ when it is
desirable to execute one or more middleware functions **after** the primary endpoint handler has finished. The value
is an array of strings, each being the name of the function to execute.
**Example**
.. code-block:: yaml
:linenos:
:emphasize-lines: 8-9
/user:
x-schema: User
post:
description: Create a new User.
x-name: create
x-before:
- validate
x-after:
- prepareOutput
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/User"
responses:
"201":
description: The newly created User.
content:
application/json:
schema:
$ref: "#/components/schemas/User"
**Generated Code**
.. code-block:: typescript
:linenos:
:emphasize-lines: 6
/**
* Create a new User.
*/
@Auth(["jwt"])
@Before(["validate"])
@After(["prepareOutput"])
@Post()
private async create(obj: User, @AuthUser user?: JWTUser): Promise {
const newObj: User = new User(obj);
throw new Error("This route is not implemented.");
}
``x-before``
~~~~~~~~~~~~
**Default Value**: ``[]``
The ``x-before`` field is applied to a `Operation Object `_ when it is
desirable to execute one or more middleware functions **before** the primary endpoint handler has finished. The value
is an array of strings, each being the name of the function to execute.
**Example**
.. code-block:: yaml
:linenos:
:emphasize-lines: 6-7
/user:
x-schema: User
post:
description: Create a new User.
x-name: create
x-before:
- validate
x-after:
- prepareOutput
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/User"
responses:
"201":
description: The newly created User.
content:
application/json:
schema:
$ref: "#/components/schemas/User"
**Generated Code**
.. code-block:: typescript
:linenos:
:emphasize-lines: 5
/**
* Create a new User.
*/
@Auth(["jwt"])
@Before(["validate"])
@After(["prepareOutput"])
@Post()
private async create(obj: User, @AuthUser user?: JWTUser): Promise {
const newObj: User = new User(obj);
throw new Error("This route is not implemented.");
}
``x-name``
~~~~~~~~~~
**Default Value**: ``null``
The ``x-name`` field is applied to a `Operation Object `_. It
defines the unique name of the operation and the function name of the generated code for the endpoint handler.
**Example**
.. code-block:: yaml
:linenos:
:emphasize-lines: 6
paths:
/pet:
x-schema: Pet
get:
description: "Multiple Pet objects"
x-name: "find"
responses:
"200":
description: A list of Pet objects.
content:
application/json:
schema:
type: "array"
items:
$ref: "#/components/schemas/Pet"
**Generated Code**
.. code-block:: typescript
:linenos:
:emphasize-lines: 5
/**
* Multiple Pet objects
*/
@Get()
private async find(@AuthUser user?: JWTUser): Promise> {
throw new Error("This route is not implemented.");
}