Criando sua API com Fastify e Prisma
Tags: prisma, node, fastify, api
Published: 2024-03-24 19:19:10

Vinicius Rodrigues - Fullstack Developer - [LinkedIn](https://www.linkedin.com/in/vinicius-rodrigues-dev)


Se você está lendo isso eu imagino que queira ter um primeiro contato com o Fastify ou esteja com alguma dúvida para iniciar o desenvolvimento da sua aplicação, sendo assim vamos direto ao ponto:


## Fastify

O Fastify é um framework assim como o express que nos fornece um servidor http, é a base do nosso projeto e o que vai nos permitir criar nossa API de forma extremamente simples. Dentre as funcionalidades do Fastify creio que devemos abordar os **Hooks**, **Decorators** e **Plugins**

### Hooks

Se você já construiu uma API já deve ter utilizado um middleware e esses "hooks" como o Fastify chama são nada mais do que middlewares. Você deve estar pensando na inutilidade disso agora mas não é bem assim, com os hooks podemos atribuir globalmente as nossas rotas todo tipo de tratamento ao qual nos for necessário. Mais a frente vamos ver um exemplo prático, por enquanto deixo este aqui: 

```typescript
fastify.addHook('preHandler', (request, reply, done) => {
  console.log('Antes de lidar com a requisição');
  done();
});
```

### Decorators

Decorators em geral são funções usadas para adicionar funcionalidades em outro código, os decorators do Fastify não fogem desse conceito pois basicamente são uma extensão da instância do Fastify.

```typescript
// Criação do decorator 'uppercase'
fastify.decorate('uppercase', function (value) {
  return value.toUpperCase();
});

fastify.get('/uppercase/:text', (request, reply) => {
// Usando o decorator 'uppercase' para converter 
// o parâmetro da rota para maiúsculas
  const uppercaseText = request.uppercase(request.params.text);
  reply.send({ uppercaseText });
});
```
Sendo assim, onde você tiver acesso a instância do fastify também será possível acessar todos os decorators.

### Plugins

Aqui nos deparamos com um dos principais conceitos do fastify, pense no plugin como uma peça de lego que sozinha pode não fazer muito sentido, cada peça tem seu formato, cor, encaixe... e os plugins podem ter diferentes funcionalidades, vou deixar uns exemplos: 

- Handler de erros
- Rotas http
- Plugin de internacionalização
- **Conexão com bancos de dados**


## Mão na massa

Instale o Fastify, fastify-plugin e Prisma

```bash
pnpm add fastify fastify-plugin prisma
```

Crie o arquivo _app.ts_, aqui vamos inicializar nosso servidor.

```typescript
// src/app.ts
import fastify from 'fastify'
import { dbPlugin } from './plugins/db-plugin'

// Registrar plugin do prisma
fastify.register(dbPlugin)

// Rota simples
fastify.get('/', (request, reply) => {
  reply.send({ hello: 'world' });
});

fastify.listen(3000, (err) => {
  if (err) {
    console.error(err);
    process.exit(1);
  }
  console.log('Servidor rodando em http://localhost:3000');
});
```

Feito isso, precisamos criar nosso plugin _db-plugin_ onde estará o prisma client.

```typescript
// src/plugins/db-plugin.ts

import fp from 'fastify-plugin';
import { PrismaClient } from '@prisma/client';

async function prismaPlugin(fastify, options) {
  const db = new PrismaClient();

  // Adiciona o objeto Prisma Client ao fastify, para que 
  // possa ser acessado em rotas e outros plugins
  fastify.decorate('db', db);

  // Se você quiser pode adicionar um **hook** para ter 
  // acesso ao **db** dentro do objeto de request.
  fastify.addHook('onRequest', (req, reply, done) => {
    req.db = db
    done();
  });

  // Fecha a conexão do Prisma Client quando o aplicativo 
  // Fastify é fechado
  fastify.addHook('onClose', async (fastifyInstance) => {
    fastifyInstance.db.$disconnect();
  });
}

export default fp(prismaPlugin);
```
 
O que eu fiz com o prisma pode ser feito com qualquer outra conexão com o banco, seja outro ORM, QueryBuilder ou o driver nativo. O mesmo vai ser aplicado pra diversas outras coisas, como um tratamento de logs, uma classe de erros global ou uma conexão com outro serviço.

Espero ter ajudado com esse pequeno artigo, tenho um projeto onde apliquei esses conceitos então vou deixa-lo [aqui](https://github.com/ViniciusRodrigues11/rocketseat-solid-api)