Skip to main content

Responses data structure

Responses#

Information about the structure of responses returned in a method is generated by the @Responses() decorator. This decorator allows you to accumulate many answer options, if it is implied by the logic of the route.

It takes as arguments a sequence of objects that satisfy the following structure:

interface OpenApiResponse {  status: number; // response status code  schema: SchemaObject | ThisRefContainer |Function | any; // a JSON-schema or an object that generates JSON in JSON-schema  contentType?: string; // content type, default `application/json`  isArray?: boolean; // a flag that a array of objects (collection) is returned, by default `false`  description?: string; // response description}

An example of how this decorator works:

// describe a typical error that can be returned@JSONSchema({  description: "standart error response",})export class ErrorResponse extends Error {  @IsNumber()  @JSONSchema({    description: "code of error",    examples: ["404", "500"],  })  status: number;
  @IsString()  @JSONSchema({    description: "error message",    examples: ["Not Found", "Access denied"],  })  message: string;
  @IsOptional()  @JSONSchema({    anyOf: [{ type: "array", items: { type: "object" } }, { type: "object" }],    description: "error details",    examples: [      `[{"property": "name", "error": "must be not empty"}]`,      `{"errors": ["wrong value", "weak password"]}`,    ],  })  data: any;
  constructor(message, status = 500, data = undefined) {    super(message);    this.status = status;    this.data = data;  }
  toJSON() {    return { message: this.message, status: this.status, data: this.data };  }
  static toJSON(): SchemaObject {    return targetConstructorToSchema(this);  }}
// ... auth.tsclass Auth {  // at the middleware add a 403 response that will apply to all endpoints requiring authorization  @Middleware()  @Responses({ status: 403, description: "access denied error", schema: ErrorResponse })  static async Required(@Headers("authorization") token, @Err(ErrorResponse) err, @Next() next) {    const authData = await models.Auth.checkToken(token);    if (authData) {      return next();    } else {      return err("access denied", 403, { token });    }  }}
// ... users.ts@Use(Auth.Required)class Users {  @Get()  @Summary("Get users list")  @Responses({    status: 200,    desciption: "Users list",    isArray: true,    schema: models.Users,  })  static Index() {    return models.Users.find();  }
  @Post()  @Summary("Add new user")  @Responses(    {      status: 200,      description: "user info",      schema: models.Users,    },    { status: 500, description: "adding user error", schema: ErrorResponse }  )  static Add(@Body() body) {    return models.Users.create({ ...body });  }}

Thus, for the methods of the route node Users, in addition to the responses declared for them, will also be added a variant with the error 403, since each of these methods requires authorization.