AzuraJS Logo
AzuraJSFramework
v2.2 Beta

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" };
}

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: RequestServer

Exemplo:

@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: ResponseServer

Exemplo:

@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: any

Exemplos:

// 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: string

Exemplos:

// 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: string

Exemplos:

// 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 | undefined

Exemplos:

// 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: string

Exemplo:

@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: string

Exemplo:

@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) => void

Exemplo:

@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:

  1. Decorator de Classe (@Controller) - Registra o controller
  2. Decorators de Método (@Get, @Post, etc.) - Registra rotas
  3. 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 });
  }
}

Próximos Passos 📖

On this page