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

1
2
3
4
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

1
2
3
4
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

1
2
3
4
5
6
 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

1
2
3
4
5
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

1
2
3
4
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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
 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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
 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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
 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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
/**
 * Handles all REST API requests for the endpoint `/user/login`.
 *
 * @author <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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
 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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
 * Handles all REST API requests for the endpoint `/pet`.
 *
 * @author <AUTHOR>
 */
@Model(Pet)
@Route("/pet")
class PetRoute extends ModelRoute<Pet> {
    @Config
    protected config: any;
    @Logger
    protected logger: any;

    @MongoRepository(Pet)
    protected repo?: Repo<Pet>;

    /**
     * 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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
 /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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
/**
 * Create a new User.
 */
@Auth(["jwt"])
@Before(["validate"])
@After(["prepareOutput"])
@Post()
private async create(obj: User, @AuthUser user?: JWTUser): Promise<User> {
    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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
 /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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
/**
 * Create a new User.
 */
@Auth(["jwt"])
@Before(["validate"])
@After(["prepareOutput"])
@Post()
private async create(obj: User, @AuthUser user?: JWTUser): Promise<User> {
    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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
 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

1
2
3
4
5
6
7
/**
 * Multiple Pet objects
 */
@Get()
private async find(@AuthUser user?: JWTUser): Promise<Array<Pet>> {
    throw new Error("This route is not implemented.");
}