swaggeropenapiswagger-jsdocs

How to write a nested object in Swagger 3.0 for components


So I am working on developing the components yaml file in the Data Transfer Object files so I can then reference them.

This is what I have so far:

/**
* @openapi
* components:
*   schemas:
*     VerifiedEmailAddressDto:
*       type: object
*       required:
*         - email
*       properties:
*         _type:
*           type: string
*         email:
*           type: string
*           description: a users email.
*         reset:
*           type: boolean
*         passwordRules:
*           type: object
*           properties:
*             minLength:
*               type: number
*             maxLength:
*               type: number
*             minRequiredUppercase:
*               type: number
*       example:
*         _type: VerifiedEmailAddressDto
*         email: pablo+test_pab001@alunacare.com
*         reset: false
*         passwordRules:
*/
export class VerifiedEmailAddressDto {
  readonly _type = "VerifiedEmailAddressDto";
  readonly email: string;
  readonly reset: boolean;
  readonly passwordRules: { minLength: number; maxLength: number; minRequiredUppercase: number; minRequiredLowerCase: number; minRequiredSymbols: number };

  constructor(email: string, reset: boolean, passwordRules: { minLength: number; maxLength: number; minRequiredUppercase: number; minRequiredLowerCase: number; minRequiredSymbols: number }) {
   this.email = email;
   this.reset = reset;
   this.passwordRules = passwordRules;
  }
}

That last property of passwordRules is an object inside this object. So it's a nested object, but what I have so far, does not give me this:

{
 "_type": "VerifiedEmailAddressDto",
 "email": "pablo+test_pab001@alunacare.com",
 "reset": false,
 "passwordRules": {
   "minLength": 8,
   "maxLength": 25,
   "minRequiredUppercase": 1,
   "minRequiredLowerCase": 1,
   "minRequiredSymbols": 0
  }
}

But honestly I am not sure how to complete this, I assume that this part:

*         passwordRules:
*           type: object
*           properties:
*             minLength:
*               type: number
*             maxLength:
*               type: number
*             minRequiredUppercase:
*               type: number

is correct, but what to offer in the example is what I am stuck on and perhaps maybe even the above in this case might not be correct.

The idea is so I can eventually property reference it here:

/**
* @openapi
* /api/v2/auth/check_mail:
*   post:
*     tags: [Auth]
*     description: This endpoint checks to see if an email is unique or is in use.
*     requestBody:
*       required: true
*       content:
*         application/json:
*           schema:
*           type: object
*           $ref: '#/components/schemas/VerifiedEmailAddressDto'
*     responses:
*       201:
*         description: Get permissions.
*         content:
*           application/json:
*             schema:
*             $ref: '#/components/schemas/VerifiedEmailAddressDto'
*/
this.app.post(p().api.v2.auth.check_email.$url, [
// TODO restrict number of queries by IP by period of time.
authMiddleware.validateEmailQuery,
credentialsController.verifyEmailAddress
]);

So I am able to get an empty object to appear for passwordRules like so:

/**
* @openapi
* components:
*   schemas:
*     VerifiedEmailAddressDto:
*       type: object
*       required:
*         - email
*       properties:
*         _type:
*           type: string
*         email:
*           type: string
*           description: a users email.
*         reset:
*           type: boolean
*         passwordRules:
*           type: object
*           properties:
*             minLength:
*               type: number
*             maxLength:
*               type: number
*             minRequiredUppercase:
*               type: number
*       example:
*         _type: VerifiedEmailAddressDto
*         email: pablo+test_pab001@alunacare.com
*         reset: false
*         passwordRules: {}
*/
export class VerifiedEmailAddressDto {
  readonly _type = "VerifiedEmailAddressDto";
  readonly email: string;
  readonly reset: boolean;
  readonly passwordRules: { minLength: number; maxLength: number; minRequiredUppercase: number; minRequiredLowerCase: number; minRequiredSymbols: number };

  constructor(email: string, reset: boolean, passwordRules: { minLength: number; maxLength: number; minRequiredUppercase: number; minRequiredLowerCase: number; minRequiredSymbols: number }) {
   this.email = email;
   this.reset = reset;
   this.passwordRules = passwordRules;
  }
}

but if I try to add its properties within the object like so:

passwordRules: {
  minLength: 8
  maxLength: 25
}

I get nothing, if I try to put the examples in like so:

  *         passwordRules:
    *           type: object
    *           properties:
    *             minLength:
    *               type: number
    *               example: 8
    *             maxLength:
    *               type: number
    *               example: 25
    *             minRequiredUppercase:
    *               type: number
    *               example: 1
    *       example:
    *         _type: VerifiedEmailAddressDto
    *         email: pablo+test_pab001@alunacare.com
    *         reset: false
    *         passwordRules: {}

I still get nothing.


Solution

  • In OpenAPI, an example nested object can be specified the same way as a root example object. E.g., as YAML key-value pairs.

    So the following example spec:

    ...
    *         passwordRules:
    *           type: object
    *           properties:
    *             minLength:
    *               type: number
    *             maxLength:
    *               type: number
    *             minRequiredUppercase:
    *               type: number
    *             minRequiredLowerCase:
    *               type: number
    *             minRequiredSymbols:
    *               type: number
    *       example:
    *         _type: VerifiedEmailAddressDto
    *         email: pablo+test_pab001@alunacare.com
    *         reset: false
    *         passwordRules:
    *           minLength: 8
    *           maxLength: 25
    *           minRequiredUppercase: 1
    *           minRequiredLowerCase: 1
    *           minRequiredSymbols: 0
    ...
    

    ..looks like this in Swagger-UI:

    swagger-ui