================== 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."); }