DEV Community

Luciano Moraes Jr.
Luciano Moraes Jr.

Posted on

Gerando Documentação de API Automática com Fastify, @fastify/swagger e Zod

Olá, devs! Neste post, vamos aprender como gerar documentação automática para uma API em uma aplicação Fastify utilizando as bibliotecas @fastify/swagger e Zod. Vamos dividir o tutorial em etapas para facilitar o entendimento.

O que é Fastify?

Fastify é um framework web altamente eficiente e focado em performance para Node.js. Ele oferece uma API simples e fácil de usar, com suporte para plugins e várias funcionalidades, tornando-o ideal para criar aplicações e APIs rápidas.

O que é Swagger?

Swagger é uma ferramenta popular que permite a criação de documentação interativa para APIs RESTful. Com Swagger, você pode visualizar e testar suas APIs diretamente na documentação, facilitando a vida dos desenvolvedores e consumidores da API.

Vantagens de Usar Swagger:

  • Interatividade: Permite que os desenvolvedores testem as APIs diretamente na documentação.
  • Clareza: Melhora a compreensão da API para desenvolvedores e usuários.

O que Vamos Precisar?

Este artigo requer conhecimento básico de Fastify e TypeScript.

  1. Uma aplicação Fastify configurada com TypeScript.
  2. As bibliotecas @fastify/swagger, zod e fastify-type-provider-zod.

Passo 1: Configurando o Projeto

Primeiro, vamos criar uma nova aplicação Fastify. Caso ainda não tenha um projeto, você pode criar um utilizando o seguinte comando:

npm init -y
npm install fastify
npm install -D typescript @types/node tsx
Enter fullscreen mode Exit fullscreen mode

Após a instalação, crie um arquivo tsconfig.json com o seguinte conteúdo:

{
  "$schema": "https://json.schemastore.org/tsconfig",
  "_version": "20.1.0",

  "compilerOptions": {
    "lib": ["es2023"],
    "module": "node16",
    "target": "es2022",

    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "moduleResolution": "node16"
  }
}
Enter fullscreen mode Exit fullscreen mode

Crie uma estrutura de pastas para o seu projeto:

mkdir src
touch src/server.ts
Enter fullscreen mode Exit fullscreen mode

Passo 2: Instalando as Dependências Necessárias

Agora, instale as bibliotecas necessárias para a geração da documentação:

npm install @fastify/swagger @fastify/swagger-ui fastify-type-provider-zod zod
Enter fullscreen mode Exit fullscreen mode

Passo 3: Configurando o Fastify com Swagger

Abra o arquivo src/server.ts e adicione a configuração do Fastify e do Swagger:

import fastifySwagger from "@fastify/swagger";
import fastifySwaggerUi from "@fastify/swagger-ui";
import fastify from "fastify";
import {
  jsonSchemaTransform,
  serializerCompiler,
  validatorCompiler,
  ZodTypeProvider
} from "fastify-type-provider-zod";
import z from "zod";


const app = fastify();

// Adicionar o validator e o serializer compiler
app.setValidatorCompiler(validatorCompiler);
app.setSerializerCompiler(serializerCompiler);

app.register(fastifySwagger, {
  openapi: {
    info: {
      title: 'API de Exemplo',
      description: 'Documentação da API de exemplo utilizando Fastify',
      version: '1.0.0',
    },
  },
  // Importante adicionar para fazer o parse do schema
  transform: jsonSchemaTransform
})

app.register(fastifySwaggerUi, {
  routePrefix: '/docs'
})

// Definição de um endpoint de exemplo
app.after(() => {
  app.withTypeProvider<ZodTypeProvider>().get('/hello', {
    schema: {
      response: {
        200: z.object({
          message: z.string(),
        }),
      },
    },
  }, async (request, reply) => {
    return reply.send({ message: 'Hello world!' })
  });
})

app
  .listen({ port: 3333 })
  .then(() => console.log('Server running on http://localhost:3333'))
Enter fullscreen mode Exit fullscreen mode

Passo 4: Executando a Aplicação

Agora, você pode executar a aplicação usando o tsx, adicione um script no package.json para executar:

...
"scripts": {
    "dev": "tsx watch src/server.ts"
  },
...
Enter fullscreen mode Exit fullscreen mode
npm run dev
Enter fullscreen mode Exit fullscreen mode

Ao acessar http://localhost:3000/docs, você verá a interface do Swagger UI com a documentação gerada automaticamente para o endpoint /hello.

Passo 5: Adicionando mais endpoints e schemas

Você pode facilmente adicionar mais endpoints e esquemas à sua API. Por exemplo, vamos adicionar um endpoint para calcular a soma de dois números:

// Definição do esquema para a requisição
const sumSchema = z.object({
  a: z.coerce.number(),
  b: z.coerce.number(),
});

// Endpoint para calcular a soma
app.after(() => {
  app.withTypeProvider<ZodTypeProvider>().get('/sum', {
    schema: {
      querystring: sumSchema,
      response: {
        200: z.object({
          result: z.number(),
        }),
      },
    },
  }, async (request, reply) => {
    const { a, b } = request.query
    const result = a + b;
    return { result };
  });
})
Enter fullscreen mode Exit fullscreen mode

Após adicionar o endpoint, a documentação do Swagger será atualizada automaticamente, permitindo que você visualize e teste a nova funcionalidade.

Bônus: Separando Rotas em Arquivos

Em alguns casos, você pode querer separar as rotas em arquivos distintos para manter a organização do seu código. Para isso, você pode utilizar os plugins do Fastify.

Aqui está um exemplo de como criar uma rota /sum em um arquivo separado:

Arquivo plugin.ts

import { FastifyPluginAsyncZod } from "fastify-type-provider-zod";
import z from "zod";

const sumSchema = z.object({
  a: z.coerce.number(),
  b: z.coerce.number(),
});

export const sumRoute: FastifyPluginAsyncZod = async app => {
  app.get('/sum', {
    schema: {
      querystring: sumSchema,
      response: {
        200: z.object({
          result: z.number(),
        }),
      }
    }
  }, async (request, reply) => {
    const { a, b } = request.query
    const result = a + b;
    return { result };
  })
}
Enter fullscreen mode Exit fullscreen mode

Atualizando o index.ts

Atualize o arquivo index.ts para registrar a nova rota:

import fastifySwagger from "@fastify/swagger";
import fastifySwaggerUi from "@fastify/swagger-ui";
import fastify from "fastify";
import {
  jsonSchemaTransform,
  serializerCompiler,
  validatorCompiler
} from "fastify-type-provider-zod";

import { sumRoute } from "./plugin";

const app = fastify();

app.setValidatorCompiler(validatorCompiler);
app.setSerializerCompiler(serializerCompiler);

app.register(fastifySwagger, {
  openapi: {
    info: {
      title: 'API de Exemplo',
      description: 'Documentação da API de exemplo utilizando Fastify',
      version: '1.0.0',
    },
  },
  transform: jsonSchemaTransform
})

app.register(fastifySwaggerUi, {
  routePrefix: '/docs'
})

app.register(sumRoute)

app
  .listen({ port: 3333 })
  .then(() => console.log('Server running on http://localhost:3333'))
Enter fullscreen mode Exit fullscreen mode

Conclusão

Pronto! Agora você tem uma aplicação Fastify com TypeScript capaz de gerar documentação automática utilizando @fastify/swagger e zod. Essa abordagem não apenas melhora a legibilidade da sua API, mas também facilita a vida dos desenvolvedores que a utilizam.

Espero que este tutorial tenha sido útil para você. Se tiver alguma dúvida, deixe um comentário abaixo. Até a próxima!


Gostou deste post? Siga-me para mais conteúdos sobre desenvolvimento web e tecnologias! 🚀

Top comments (0)