Decorators
Guia completo de todos os decorators do AzuraJS
Decorators 🏷️
AzuraJS fornece um rico conjunto de decorators TypeScript para construir APIs elegantes e type-safe.
Decorators de Classe 🎯
@Controller
Define uma classe controller com um caminho base opcional.
@Controller(prefix?: string)Exemplos:
import { Controller } from "azurajs/decorators";
// Com prefixo
@Controller("/api/users")
export class UserController {}
// Sem prefixo
@Controller()
export class RootController {}
// Caminho aninhado
@Controller("/api/v1/admin/users")
export class AdminUserController {}Decorators de Método 🛣️
Decorators de método definem rotas HTTP para métodos do controller.
@Get
Define uma rota GET.
@Get(path?: string)Exemplos:
import { Controller, Get } from "azurajs/decorators";
@Controller("/api/users")
export class UserController {
@Get() // GET /api/users
getAll() {}
@Get("/:id") // GET /api/users/:id
getOne() {}
@Get("/search") // GET /api/users/search
search() {}
}@Post
Define uma rota POST.
@Post(path?: string)Exemplo:
import { Post, Body } from "azurajs/decorators";
@Post() // POST /api/users
createUser(@Body() data: any) {
return { id: Date.now(), ...data };
}@Put
Define uma rota PUT para atualizações completas.
@Put(path?: string)Exemplo:
@Put("/:id") // PUT /api/users/:id
updateUser(@Param("id") id: string, @Body() data: any) {
return { id, ...data };
}@Patch
Define uma rota PATCH para atualizações parciais.
@Patch(path?: string)Exemplo:
@Patch("/:id") // PATCH /api/users/:id
patchUser(@Param("id") id: string, @Body() data: Partial<User>) {
return { id, ...data };
}@Delete
Define uma rota DELETE.
@Delete(path?: string)Exemplo:
@Delete("/:id") // DELETE /api/users/:id
deleteUser(@Param("id") id: string) {
return { message: "Usuário deletado" };
}@Head
Define uma rota HEAD (para verificar existência de recurso).
@Head(path?: string)Exemplo:
@Head("/:id") // HEAD /api/users/:id
checkExists(@Param("id") id: string, @Res() res: ResponseServer) {
const exists = users.some(u => u.id === id);
res.status(exists ? 200 : 404).end();
}@Options
Define uma rota OPTIONS (tipicamente para preflight CORS).
@Options(path?: string)Exemplo:
@Options() // OPTIONS /api/users
handleOptions(@Res() res: ResponseServer) {
res.set("Allow", "GET, POST, PUT, DELETE").end();
}Decorators de Parâmetro 🔖
Decorators de parâmetro injetam dados nos parâmetros de métodos do controller.
@Req
Injeta o objeto de requisição completo.
@Req() req: RequestServerExemplo:
@Get("/info")
getInfo(@Req() req: RequestServer) {
return {
method: req.method,
url: req.url,
headers: req.headers
};
}@Res
Injeta o objeto de resposta para controle manual.
@Res() res: ResponseServerExemplo:
@Get("/download")
download(@Res() res: ResponseServer) {
res.setHeader("Content-Type", "application/octet-stream");
res.setHeader("Content-Disposition", "attachment; filename=arquivo.zip");
res.send(fileBuffer);
}@Body
Extrai o corpo da requisição (automaticamente parseado para JSON e form data).
@Body() body: anyExemplos:
// Corpo completo
@Post()
create(@Body() data: CreateUserDto) {
return { id: Date.now(), ...data };
}
// Acessar propriedades do corpo diretamente
@Post()
create(@Body() { name, email }: { name: string; email: string }) {
return { name, email };
}@Param
Extrai parâmetros de rota do caminho da URL.
@Param(name?: string) param: stringExemplos:
// Parâmetro único
@Get("/:id")
getUser(@Param("id") id: string) {
return { id };
}
// Múltiplos parâmetros
@Get("/:userId/posts/:postId")
getPost(
@Param("userId") userId: string,
@Param("postId") postId: string
) {
return { userId, postId };
}
// Todos os parâmetros
@Get("/:userId/posts/:postId")
getPost(@Param() params: Record<string, string>) {
return params; // { userId: "1", postId: "2" }
}@Query
Extrai parâmetros de query string.
@Query(name?: string) query: stringExemplos:
// Parâmetro de query único
@Get("/search")
search(@Query("q") searchTerm: string) {
return { results: [], query: searchTerm };
}
// Múltiplos parâmetros de query
@Get("/filter")
filter(
@Query("status") status: string,
@Query("limit") limit: string
) {
return { status, limit };
}
// Todos os parâmetros de query
@Get("/search")
search(@Query() query: Record<string, string>) {
// GET /api/users/search?q=john&limit=10
return query; // { q: "john", limit: "10" }
}@Headers
Extrai cabeçalhos da requisição.
@Headers(name?: string) header: string | undefinedExemplos:
// Cabeçalho único
@Get("/protected")
getData(@Headers("authorization") auth: string) {
if (!auth) {
throw new HttpError(401, "Não autorizado");
}
return { data: "secreto" };
}
// Múltiplos cabeçalhos
@Get("/info")
getInfo(
@Headers("user-agent") ua: string,
@Headers("accept-language") lang: string
) {
return { userAgent: ua, language: lang };
}
// Todos os cabeçalhos
@Get("/headers")
getAllHeaders(@Headers() headers: Record<string, string>) {
return { headers };
}@Ip
Extrai o endereço IP do cliente.
@Ip() ip: stringExemplo:
@Post("/login")
login(@Body() credentials: any, @Ip() ip: string) {
console.log(`Tentativa de login de ${ip}`);
// Autenticar usuário
return { success: true };
}@UserAgent
Extrai o cabeçalho User-Agent.
@UserAgent() userAgent: stringExemplo:
@Get("/stats")
trackVisit(@UserAgent() ua: string, @Ip() ip: string) {
console.log(`Visita de ${ip} usando ${ua}`);
return { message: "Visita registrada" };
}@Next
Injeta a função next para cadeias de middleware.
@Next() next: (err?: unknown) => voidExemplo:
@Get("/async")
async handleAsync(
@Req() req: RequestServer,
@Res() res: ResponseServer,
@Next() next: () => void
) {
try {
const data = await fetchData();
res.json({ data });
} catch (error) {
next(error);
}
}Combinando Decorators 🔗
Você pode combinar múltiplos decorators de parâmetro em um método:
@Controller("/api/posts")
export class PostController {
@Get("/:id/comments")
getComments(
@Param("id") postId: string,
@Query("limit") limit: string,
@Query("offset") offset: string,
@Headers("authorization") auth: string,
@Ip() ip: string,
@Res() res: ResponseServer
) {
// Verificar autenticação
if (!auth) {
return res.status(401).json({ error: "Não autorizado" });
}
// Registrar requisição
console.log(`${ip} solicitou comentários do post ${postId}`);
// Retornar comentários
const comments = getCommentsFromDB(postId, Number(limit), Number(offset));
res.json({ comments });
}
@Post("/:id/comments")
createComment(
@Param("id") postId: string,
@Body() data: CreateCommentDto,
@Ip() ip: string,
@UserAgent() ua: string,
@Res() res: ResponseServer
) {
const comment = {
id: Date.now(),
postId,
...data,
metadata: { ip, userAgent: ua }
};
res.status(201).json({ comment });
}
}Ordem de Execução dos Decorators ⚡
Decorators são executados nesta ordem:
- Decorator de Classe (
@Controller) - Registra o controller - Decorators de Método (
@Get,@Post, etc.) - Registra rotas - Decorators de Parâmetro (
@Body,@Param, etc.) - Executados em runtime quando a rota é chamada
Segurança de Tipos com Decorators 🔒
Use interfaces TypeScript para melhor segurança de tipos:
interface CreatePostDto {
title: string;
content: string;
tags: string[];
}
interface UpdatePostDto {
title?: string;
content?: string;
tags?: string[];
}
@Controller("/api/posts")
export class PostController {
@Post()
create(@Body() data: CreatePostDto, @Res() res: ResponseServer) {
// data é totalmente tipado
const post = {
id: Date.now(),
title: data.title,
content: data.content,
tags: data.tags
};
res.status(201).json({ post });
}
@Patch("/:id")
update(
@Param("id") id: string,
@Body() data: UpdatePostDto,
@Res() res: ResponseServer
) {
// TypeScript sabe que todos os campos são opcionais
res.json({ id, ...data });
}
}