Fundamentos do Next.js 15
Configurando um Banco de Dados (Ex: Prisma com PostgreSQL)
Aprenda sobre configurando um banco de dados (ex: prisma com postgresql)
Módulo 5: Projeto Final: Construindo uma Aplicação Full Stack
Aula: Configurando um Banco de Dados (Ex: Prisma com PostgreSQL)
Olá, futuros desenvolvedores Full Stack! 👋
Nesta aula prática, daremos um passo crucial na construção da nossa aplicação Next.js: a configuração de um banco de dados. Uma aplicação Full Stack robusta precisa persistir dados, e para isso, utilizaremos o PostgreSQL, um dos bancos de dados relacionais mais poderosos e populares, combinado com o Prisma, um ORM (Object-Relational Mapper) moderno que simplifica drasticamente a interação com o banco de dados em aplicações Node.js e TypeScript.
Ao final desta aula, você terá seu ambiente de desenvolvimento configurado para trabalhar com um banco de dados relacional, pronto para armazenar e gerenciar os dados da sua aplicação Next.js 15! 🚀
1. Introdução: A Necessidade de um Banco de Dados
Até agora, nossas aplicações Next.js podem ter sido mais focadas na interface do usuário e na lógica de renderização. No entanto, para construir uma aplicação real e dinâmica, precisamos de um lugar para armazenar informações de forma persistente. Pense em usuários, produtos, posts de blog, pedidos – tudo isso precisa ser salvo e recuperado.
É aqui que entram os bancos de dados! Eles são sistemas organizados para armazenar, gerenciar e recuperar grandes volumes de dados.
- PostgreSQL: Escolhemos o PostgreSQL por sua robustez, conformidade com padrões SQL, extensibilidade e uma comunidade vibrante. É uma excelente escolha para aplicações de todos os tamanhos.
- Prisma: O Prisma atua como uma camada entre sua aplicação Next.js e o PostgreSQL. Ele permite que você defina seu esquema de banco de dados usando um DSL (Domain Specific Language) intuitivo e, em seguida, gera um cliente TypeScript que você usa para interagir com o banco de dados de forma segura e com autocompletar. Adeus SQL puro e olá tipos seguros! ✨
2. Explicação Detalhada: Preparando Nosso Ambiente
Vamos configurar o PostgreSQL e o Prisma em nosso projeto Next.js.
2.1. Configurando o PostgreSQL
Para fins de desenvolvimento, a maneira mais fácil e recomendada de rodar um banco de dados PostgreSQL é usando Docker. Se você não tem Docker instalado, por favor, instale-o antes de prosseguir.
-
Crie um arquivo
docker-compose.ymlna raiz do seu projeto Next.js (ou em uma pastadocker/se preferir):# docker-compose.yml version: '3.8' services: db: image: postgres:16 restart: always environment: POSTGRES_USER: user POSTGRES_PASSWORD: password POSTGRES_DB: nextjs_db ports: - "5432:5432" volumes: - db_data:/var/lib/postgresql/data volumes: db_data:image: postgres:16: Usamos a versão 16 do PostgreSQL.environment: Define as credenciais e o nome do banco de dados. Mantenha-os seguros em produção!ports: "5432:5432": Mapeia a porta 5432 do container para a porta 5432 da sua máquina local.volumes: db_data:/var/lib/postgresql/data: Persiste os dados do banco de dados mesmo se o container for removido.
-
Inicie o container PostgreSQL:
Abra seu terminal na raiz do projeto e execute:
docker-compose up -dIsso iniciará o container do PostgreSQL em segundo plano. Você pode verificar seu status com
docker-compose ps.
2.2. Instalando e Inicializando o Prisma
Agora que temos nosso banco de dados rodando, vamos integrar o Prisma.
-
Instale o Prisma CLI como dependência de desenvolvimento:
npm install prisma --save-devou
yarn add prisma --devou
pnpm add prisma --save-dev -
Inicialize o Prisma em seu projeto:
Este comando cria a estrutura inicial do Prisma, incluindo o arquivo
schema.prismae configura o arquivo.env.npx prisma initVocê verá algo como:
✔ Your Prisma schema was created at prisma/schema.prisma ✔ You added the Prisma extension to your VS Code (optional) ✔ Wrote `.env` file with DATABASE_URL preset for PostgreSQL.Isso cria uma pasta
prismacom o arquivoschema.prismadentro e um arquivo.envna raiz do seu projeto. -
Configure a variável de ambiente
DATABASE_URL:Abra o arquivo
.envque foi criado e certifique-se de que aDATABASE_URLaponte para o seu banco de dados PostgreSQL local (conforme configurado nodocker-compose.yml).# .env DATABASE_URL="postgresql://user:password@localhost:5432/nextjs_db?schema=public"user: O usuário do banco de dados.password: A senha do banco de dados.localhost:5432: Onde seu banco de dados está rodando.nextjs_db: O nome do banco de dados.
2.3. Definindo o Schema do Prisma
O schema.prisma é o coração do Prisma. É onde você define seus modelos de dados de forma declarativa.
-
Abra
prisma/schema.prismae ele deve se parecer com isto:// prisma/schema.prisma generator client { provider = "prisma-client-js" } datasource db { provider = "postgresql" url = env("DATABASE_URL") } -
Defina seu primeiro modelo: Vamos adicionar um modelo
User(Usuário) ePost(Publicação) para nossa aplicação.// prisma/schema.prisma generator client { provider = "prisma-client-js" } datasource db { provider = "postgresql" url = env("DATABASE_URL") } // Nossos modelos de dados model User { id String @id @default(uuid()) email String @unique name String? posts Post[] createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } model Post { id String @id @default(uuid()) title String content String? published Boolean @default(false) author User @relation(fields: [authorId], references: [id]) authorId String createdAt DateTime @default(now()) updatedAt DateTime @updatedAt }model User: Define a tabelaUserno banco de dados.id: Chave primária, do tipoString, gerada automaticamente com um UUID.email: String única.name: String opcional.posts: Um array dePosts, indicando um relacionamento um-para-muitos (um usuário pode ter muitos posts).
model Post: Define a tabelaPost.author: Relacionamento com o modeloUser.authorId: Chave estrangeira que ligaPostaUser.
2.4. Migrando o Banco de Dados e Gerando o Prisma Client
Com o schema definido, precisamos aplicá-lo ao nosso banco de dados.
-
Crie e aplique a primeira migração:
npx prisma migrate dev --name initmigrate dev: Cria uma nova migração SQL e a aplica ao seu banco de dados de desenvolvimento.--name init: Dá um nome descritivo à sua migração.
Este comando fará o seguinte:
- Detectará as mudanças no seu
schema.prisma. - Gerará um arquivo SQL na pasta
prisma/migrations. - Aplicará esse SQL ao seu banco de dados PostgreSQL.
- Gerará o Prisma Client (o pacote
node_modules/@prisma/client) que você usará para interagir com o banco de dados.
2.5. Utilizando o Prisma Client em Next.js
Agora que o Prisma Client está gerado, podemos usá-lo em nossa aplicação Next.js. É uma boa prática criar uma instância global do Prisma Client para evitar instanciar múltiplos clientes em hot-reloads durante o desenvolvimento.
-
Crie um arquivo
lib/prisma.ts:// lib/prisma.ts import { PrismaClient } from '@prisma/client'; // Adiciona o Prisma Client ao objeto global do Node.js // Isso garante que apenas uma instância do Prisma Client seja criada // durante o desenvolvimento (especialmente com hot-reloading do Next.js) declare global { var prisma: PrismaClient | undefined; } const prisma = global.prisma || new PrismaClient({ log: ['query'], // Opcional: loga todas as queries SQL executadas }); if (process.env.NODE_ENV === 'development') global.prisma = prisma; export default prisma; -
Exemplo de uso em uma API Route (Next.js App Router):
Vamos criar uma API Route para buscar e criar usuários.
// app/api/users/route.ts import { NextResponse } from 'next/server'; import prisma from '@/lib/prisma'; // Importa a instância do Prisma Client // Manipula requisições GET para /api/users export async function GET() { try { const users = await prisma.user.findMany({ include: { posts: true, // Inclui os posts de cada usuário }, }); return NextResponse.json(users, { status: 200 }); } catch (error) { console.error("Erro ao buscar usuários:", error); return NextResponse.json({ error: 'Erro ao buscar usuários' }, { status: 500 }); } } // Manipula requisições POST para /api/users export async function POST(request: Request) { try { const { email, name } = await request.json(); if (!email) { return NextResponse.json({ error: 'Email é obrigatório' }, { status: 400 }); } const newUser = await prisma.user.create({ data: { email, name, }, }); return NextResponse.json(newUser, { status: 201 }); } catch (error) { console.error("Erro ao criar usuário:", error); return NextResponse.json({ error: 'Erro ao criar usuário' }, { status: 500 }); } }Agora você tem endpoints que podem interagir com seu banco de dados! Você pode testá-los usando ferramentas como Postman, Insomnia ou até mesmo
curl.- GET
/api/users: Retorna todos os usuários (e seus posts). - POST
/api/users: Cria um novo usuário. Exemplo de corpo da requisição:{ "email": "joao@example.com", "name": "João da Silva" }
- GET
3. Exercícios Práticos: Mãos à Obra! 💻
É hora de aplicar o que aprendemos. Siga os passos abaixo para configurar seu próprio banco de dados e Prisma.
Tarefas:
-
1. Iniciar o PostgreSQL com Docker:
- Verifique se o Docker está rodando em sua máquina.
- Crie o arquivo
docker-compose.ymlna raiz do seu projeto. - Execute
docker-compose up -dno terminal. - Verifique se o container
dbestá ativo comdocker-compose ps.
-
2. Instalar e Inicializar o Prisma:
- No seu terminal, na raiz do projeto Next.js, execute
npm install prisma --save-dev. - Em seguida, execute
npx prisma init. - Verifique se os arquivos
.enveprisma/schema.prismaforam criados.
- No seu terminal, na raiz do projeto Next.js, execute
-
3. Configurar
DATABASE_URL:- Abra o arquivo
.enve ajuste aDATABASE_URLpara:DATABASE_URL="postgresql://user:password@localhost:5432/nextjs_db?schema=public"
- Abra o arquivo
-
4. Definir o Schema do Prisma:
- Abra
prisma/schema.prismae adicione os modelosUserePostconforme o exemplo fornecido na seção 2.3.
- Abra
-
5. Executar Migrações:
- No terminal, execute
npx prisma migrate dev --name setup_user_and_post_models. - Confirme a criação da migração quando solicitado.
- No terminal, execute
-
6. Criar o Prisma Client Singleton:
- Crie o arquivo
lib/prisma.tse adicione o código para instanciar o Prisma Client de forma segura para o Next.js.
- Crie o arquivo
-
7. Implementar uma API Route:
- Crie o arquivo
app/api/users/route.ts(ou a rota equivalente no seu projeto) e implemente as funçõesGETePOSTpara interagir com o modeloUserusando o Prisma Client.
- Crie o arquivo
-
8. Testar a API:
- Inicie seu servidor de desenvolvimento Next.js:
npm run dev. - Use seu navegador para acessar
http://localhost:3000/api/users(deve retornar um array vazio[]inicialmente). - Use uma ferramenta como Postman, Insomnia ou
curlpara fazer uma requisiçãoPOSTparahttp://localhost:3000/api/userscom um corpo JSON para criar um usuário. - Faça um
GETnovamente para confirmar que o usuário foi criado.
- Inicie seu servidor de desenvolvimento Next.js:
Desafios (Opcional):
- 1. Adicionar um novo modelo: Crie um novo modelo
Categorynoschema.prismae relacione-o com o modeloPost(um post pode ter uma categoria, uma categoria pode ter muitos posts). - 2. Criar API Routes para
Post: ImplementeGET(todos e por ID) ePOSTpara o modeloPost. Lembre-se de como associar umPosta umUserexistente. - 3. Seed do Banco de Dados: Explore como usar Prisma Seeding para popular seu banco de dados com dados iniciais para desenvolvimento.
4. Resumo e Próximos Passos
Parabéns! 🎉 Você configurou com sucesso um banco de dados PostgreSQL e integrou o Prisma em sua aplicação Next.js. Esta é uma base sólida para qualquer aplicação Full Stack.
Nesta aula, você aprendeu a:
- Configurar um banco de dados PostgreSQL usando Docker.
- Instalar e inicializar o Prisma em seu projeto Next.js.
- Definir modelos de dados usando o
schema.prisma. - Gerar e aplicar migrações para o banco de dados.
- Utilizar o Prisma Client para interagir com o banco de dados em API Routes do Next.js.
Com o banco de dados configurado, a porta está aberta para construir funcionalidades complexas, como autenticação de usuários, gerenciamento de conteúdo e muito mais.
Próximos Passos: Na próxima aula, vamos explorar como conectar a interface do usuário com esses dados, talvez construindo formulários para criar usuários e listando-os em um componente React. Fique ligado! 🚀