OpenAPI (Swagger)
O Bunstone fornece suporte nativo à documentação OpenAPI (Swagger) usando decorators, de forma semelhante ao NestJS.
Instalação
O suporte a OpenAPI já vem embutido, mas você precisa habilitá-lo no seu AppStartup.
Configuração
Habilite o Swagger nas opções de AppStartup.create:
await AppStartup.create(AppModule, {
swagger: {
path: "/docs", // o padrão é /swagger
documentation: {
info: {
title: "Minha API",
version: "1.0.0",
description: "Documentação da API",
},
},
},
}).listen(3000);Proteção com Basic Auth
Opcionalmente, você pode proteger a página de documentação do Swagger com autenticação HTTP Basic fornecendo credenciais em auth:
await AppStartup.create(AppModule, {
swagger: {
path: "/docs",
auth: {
username: "admin",
password: "secret",
},
documentation: {
info: {
title: "Minha API",
version: "1.0.0",
},
},
},
}).listen(3000);Quando auth está definido, qualquer requisição para o caminho da documentação (e seus subcaminhos, como /docs/json) exigirá um header válido Authorization: Basic <base64(username:password)>. Requisições não autenticadas recebem uma resposta 401 Unauthorized com um desafio WWW-Authenticate, o que faz os navegadores exibirem uma caixa de login nativa. Por segurança, você só deve expor esse endpoint via HTTPS (ou atrás de um proxy reverso que finalize o HTTPS), já que as credenciais de Basic Auth, caso contrário, são enviadas em texto claro e podem ser interceptadas.
Decorators
@ApiTags()
Adiciona tags a um controller ou a um método específico.
@ApiTags("Usuários")
@Controller("users")
export class UserController {
@ApiTags("Perfil")
@Get("profile")
getProfile() {}
}@ApiOperation()
Define o resumo e a descrição de um endpoint.
@ApiOperation({ summary: 'Criar um usuário', description: 'Este endpoint cria um novo usuário no banco de dados' })
@Post()
create() {}@ApiResponse()
Define as possíveis respostas para um endpoint.
@ApiResponse({ status: 200, description: 'Usuário encontrado' })
@ApiResponse({ status: 404, description: 'Usuário não encontrado' })
@Get(':id')
findOne() {}@ApiHeader() / @ApiHeaders()
Define headers personalizados para um endpoint ou controller.
@ApiHeader({ name: "X-Custom-Header", description: "Um header personalizado" })
@Controller("users")
export class UserController {
@ApiHeaders([
{ name: "X-Token", description: "Token de autenticação", required: true },
{ name: "X-Version", description: "Versão da API" },
])
@Get()
findAll() {}
}DTOs e Schemas
O Bunstone usa Zod para validação. Quando você usa @Body(Schema), @Query(Schema) ou @Param(Schema), o schema é automaticamente registrado na documentação OpenAPI.
const CreateUserSchema = z.object({
name: z.string(),
email: z.string().email()
});
@Post()
@ApiOperation({ summary: 'Criar usuário' })
create(@Body(CreateUserSchema) body: any) {
return body;
}Exemplo prático
Explore uma configuração completa de OpenAPI e seu uso:
import {
Module,
Controller,
Get,
Post,
Body,
AppStartup,
ApiTags,
ApiOperation,
ApiResponse,
} from "../../index";
import { z } from "zod";
const UserSchema = z.object({
id: z.string(),
name: z.string(),
});
@ApiTags("Users")
@Controller("users")
class UserController {
@Get()
@ApiOperation({ summary: "List all users" })
@ApiResponse({ status: 200, description: "Return all users" })
getUsers() {
return [];
}
@Post()
@ApiOperation({ summary: "Create a user" })
@ApiResponse({ status: 201, description: "User created" })
createUser(@Body(UserSchema) body: z.infer<typeof UserSchema>) {
return body;
}
}
@Module({
controllers: [UserController],
})
class AppModule {}
const app = await AppStartup.create(AppModule, {
swagger: {
path: "/docs",
title: "Bunstone API",
version: "1.0.0",
},
});
app.listen(3000, () => {
console.log("OpenAPI (Swagger) is available at http://localhost:3000/docs");
});