Skip to content
On this page

Examples

Study after study shows that examples are a crucial part of learning new APIs (1, 2, 3). While certain issues, like type mismatches can be avoided by inferring examples from the JSON Schema (like the examples SwaggerUI automatically generates*), it's often a lot more intuitive if we provide certain examples ourselves.

* Which is limited as well, i.e. patterns will be ignored, and just sending the string "string" every time is somewhat suboptimal if that string actually carries meaning.

TIP

tsoa does not (yet) check your JSDoc examples. Incorrect examples will not break your compilation, because OpenAPI explicitly allows anything. You may also just want to demonstrate tsoa's validation 😏

We recommend using a linter (we love Spectral) to ensure your specifications aren't just correct, but also contain descriptions and correct examples.

WARNING

OpenAPI 2 only allows one example per model/property/parameter. If you defined more than one example in OpenAPI 2, tsoa will only apply first one as value. OpenAPI 3 examples is now supported!

Response examples

In order to provide an example response, tsoa offers a @Example() Decorator.

TIP

Providing the type you're writing the example for as a type argument T to

ts
@Example<T>(example: T)

is not necessary, but may help you catch bugs.

This decorator is used to specify a response for the default response, but you can add examples for other responses (@Response(), used for additional responses, often caused by errors by providing them as the third argument as well.

Default response

ts
@Route("users")
export class UsersController extends Controller {
  @Example<User>({
    id: "52907745-7672-470e-a803-a2f8feb52944",
    name: "tsoa user",
    email: "hello@tsoa.com",
    phoneNumbers: [],
    status: "Happy",
  })
  @Get("{userId}")
  public async getUser(
    @Path() userId: UUID,
    @Query() name: string
  ): Promise<User> {
    return new UsersService().get(userId, name);
  }
}

Additional Responses

ts
@Route("users")
export class UsersController extends Controller {
  /**
   * Add a new user. Remember that the demo API will not persist this data.
   *
   */
  @Post()
  @SuccessResponse("201", "Created") // Custom success response
  @Response<ValidateErrorJSON>(422, "Validation Failed", {
    message: "Validation failed",
    details: {
      requestBody: {
        message: "id is an excess property and therefore not allowed",
        value: "52907745-7672-470e-a803-a2f8feb52944",
      },
    },
  })
  public async createUser(
    @Body() requestBody: UserCreationParams
  ): Promise<void> {
    this.setStatus(201); // set return status 201
    new UsersService().create(requestBody);
    return;
  }
}

Parameter examples

WARNING

You may expect to see an example for a type reference (to a type alias, interface or a class) if you set one. However, since it'll be transformed to a reference ($ref) to the schema, the example must be ignored, since any properties that are placed next to $ref (OpenAPI's mechanism to link to the UserCreationParams schema) must be ignored.

For more info, check out the relevant parts of the OpenAPI Specification and JSON Schema Core

ts
@Route("users")
export class UsersController extends Controller {
  /**
   * @example userId "52907745-7672-470e-a803-a2f8feb52944"
   * @example userId "e77ef155-bd12-46f0-8559-bf55f6dd4c63"
   */
  @Get("{userId}")
  public async getUser(
    @Path() userId: UUID,
    @Query() name: string
  ): Promise<User> {
    return new UsersService().get(userId, name);
  }
}

Model examples

WARNING

Both OpenAPI 2 and 3 supports only single example in model. If you use more than one example, it will only apply the first one.

ts
/**
 * Stringified UUIDv4.
 * See [RFC 4112](https://tools.ietf.org/html/rfc4122)
 * @pattern [0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-4[0-9A-Fa-f]{3}-[89ABab][0-9A-Fa-f]{3}-[0-9A-Fa-f]{12}
 * @example "52907745-7672-470e-a803-a2f8feb52944"
 */
export type UUID = string;

WARNING

Any example with object or array should be in correct JSON-format. Otherwise, tsoa will throws error while generating OAS.

ts
/**
 * User objects allow you to associate actions performed in the system with the user that performed them.
 * The User object contains common information across every user in the system regardless of status and role.
 *
 *
 * @example {
 *  "id": "52907745-7672-470e-a803-a2f8feb52944",
 *  "name": "John Doe",
 *  "phoneNumbers": []
 * }
 */
export interface User {
  id: UUID;

  /**
   * The email the user used to register his account
   */
  email?: string;

  name: string;
  status?: "Happy" | "Sad";
  phoneNumbers: string[];
}

Property examples

WARNING

You may expect to see an example for the id if you set one. However, since it'll be transformed to a reference to the UUID schema, the example must be ignored, since any properties that are placed next to $ref (OpenAPI's mechanism to link to the UUID schema) must be ignored.

For more info, check out the relevant parts of the OpenAPI Specification and JSON Schema Core

ts
export interface User {
  id: UUID;

  /**
   * The email the user used to register his account
   */
  email?: string;

  name: string;

  /**
   * @example "Happy"
   */
  status?: "Happy" | "Sad";

  phoneNumbers: string[];
}