Fundamentos do Next.js 15
Planejamento e Estrutura de uma Aplicação Full Stack
Aprenda sobre planejamento e estrutura de uma aplicação full stack
Módulo 5: Projeto Final: Construindo uma Aplicação Full Stack
Aula: Planejamento e Estrutura de uma Aplicação Full Stack
Olá! 👋 Bem-vindo(a) à primeira aula do nosso módulo final. Chegamos ao ponto onde todo o conhecimento adquirido sobre Next.js 15 será consolidado na construção de uma aplicação full stack completa. Mas, antes de mergulharmos no código, precisamos de um passo crucial: planejamento e estruturação.
1. Introdução: A Importância do Planejamento 🗺️
Construir uma aplicação full stack pode ser complexo. Envolve não apenas o que o usuário vê (o frontend), mas também a lógica de negócio, o gerenciamento de dados e a segurança (o backend). Sem um plano claro, seu projeto pode rapidamente se tornar um emaranhado de arquivos e funcionalidades difíceis de manter e escalar.
Nesta aula, vamos explorar os pilares do planejamento para uma aplicação Next.js 15 full stack, garantindo que você comece seu projeto final com uma base sólida e bem organizada. Pense nesta etapa como a planta de um edifício: sem ela, a construção seria caótica e propensa a erros.
2. Explicação Detalhada: Pilares de uma Aplicação Full Stack com Next.js 15 🏗️
No contexto do Next.js 15, "full stack" significa utilizar as capacidades do framework para gerenciar tanto a interface do usuário (com React, Server Components e Client Components) quanto a lógica de servidor (com Server Actions, API Routes e Middleware).
Vamos detalhar os principais pontos a serem considerados no planejamento:
2.1. Definição de Requisitos 📝
Antes de tudo, você precisa saber o que sua aplicação fará.
- Requisitos Funcionais: O que a aplicação deve fazer? (Ex: "Usuários podem se cadastrar e fazer login", "Usuários podem criar, editar e excluir posts", "A aplicação deve exibir uma lista de produtos").
- Requisitos Não-Funcionais: Como a aplicação deve ser? (Ex: "A aplicação deve ser responsiva", "A aplicação deve ser rápida", "A aplicação deve ser segura").
- Modelagem de Dados: Quais entidades sua aplicação terá e como elas se relacionam? (Ex:
User,Post,Comment). Desenhe um diagrama de entidade-relacionamento (ERD) simples.
2.2. Arquitetura e Estrutura de Pastas 📂
O Next.js 15, com o App Router, já oferece uma estrutura robusta. No entanto, para uma aplicação full stack, é crucial organizar bem os arquivos de backend e frontend.
Estrutura Recomendada:
my-fullstack-app/
├── app/ # Rotas e UI (Server/Client Components)
│ ├── (auth)/ # Grupo de rotas para autenticação (login, register)
│ │ ├── login/
│ │ └── register/
│ ├── dashboard/ # Rotas protegidas
│ │ ├── page.tsx
│ │ └── layout.tsx
│ ├── api/ # API Routes RESTful (se necessário)
│ │ └── users/
│ │ └── route.ts
│ └── page.tsx # Página inicial
├── components/ # Componentes React reutilizáveis (Client/Server)
│ ├── ui/ # Componentes de UI genéricos (botões, inputs)
│ └── specific/ # Componentes específicos da aplicação
├── lib/ # Lógica de negócio, utilitários, conexão com DB
│ ├── actions.ts # Server Actions
│ ├── data.ts # Funções de acesso a dados (leitura)
│ ├── db.ts # Configuração do banco de dados (ex: Prisma client)
│ └── utils.ts # Funções utilitárias
├── public/ # Ativos estáticos
├── prisma/ # Esquema do banco de dados (se usar Prisma)
│ └── schema.prisma
├── auth.ts # Configuração de autenticação (ex: NextAuth.js)
├── middleware.ts # Lógica de middleware
└── tsconfig.json # Configuração do TypeScript
app/: O coração da sua aplicação, onde as rotas e a UI vivem. Use convenções de grupos de rotas(grupo)para organizar logicamente.lib/: Este é um diretório chave para abstrair a lógica de backend.lib/actions.ts: Contém suas Server Actions, que são funções assíncronas que rodam no servidor e podem ser chamadas diretamente do frontend. São ideais para mutações de dados.lib/data.ts: Funções para buscar dados do banco de dados (leitura), que podem ser usadas por Server Components ou Server Actions.lib/db.ts: Configuração e instância do seu cliente de banco de dados (ex: Prisma Client).
api/: Para API Routes tradicionais (RESTful) que você pode precisar para integrações com serviços de terceiros ou para expor um endpoint que não se encaixa bem em uma Server Action.components/: Mantenha seus componentes de UI organizados aqui.
2.3. Gerenciamento de Estado (Frontend) ⚛️
Para o frontend, o Next.js 15, com Server Components, já reduz a necessidade de gerenciamento de estado complexo. No entanto, para interações no lado do cliente:
useStateeuseContext: Para estado local de componentes e estado global simples.- Bibliotecas de Gerenciamento de Estado: Para aplicações mais complexas, considere Zustand, Redux Toolkit, ou TanStack Query (para cache de dados).
2.4. Autenticação e Autorização 🔐
Essencial para a maioria das aplicações full stack.
- NextAuth.js (Auth.js): A solução recomendada e mais robusta para autenticação em Next.js. Suporta diversos provedores (Google, GitHub, email/senha) e é altamente configurável.
- Middleware: Use o
middleware.tsdo Next.js para proteger rotas e verificar a autenticação antes que a requisição chegue à página. - Server Actions/Components: Permitem verificar a sessão do usuário diretamente no servidor para renderização condicional ou proteção de dados.
2.5. Banco de Dados 💾
A escolha do banco de dados depende dos requisitos do seu projeto.
- SQL (PostgreSQL, MySQL, SQLite): Para dados relacionais, onde a integridade é crucial.
- NoSQL (MongoDB, DynamoDB): Para dados flexíveis, escalabilidade horizontal.
- ORMs (Object-Relational Mappers): Prisma é altamente recomendado para Next.js. Ele gera um cliente de banco de dados seguro e tipado, facilitando a interação com o DB.
2.6. APIs e Lógica de Backend com Next.js 15 🚀
Aqui é onde o Next.js 15 brilha na parte full stack.
-
Server Actions: Funções assíncronas que rodam no servidor e podem ser invocadas diretamente de Client Components ou Server Components. Ideais para mutações (criar, atualizar, deletar dados).
'use client'; // Este é um Client Component import { createPost } from '@/lib/actions'; import { useFormStatus } from 'react-dom'; function SubmitButton() { const { pending } = useFormStatus(); return ( <button type="submit" disabled={pending}> {pending ? 'Criando...' : 'Criar Post'} </button> ); } export function CreatePostForm() { return ( <form action={createPost}> <input type="text" name="title" placeholder="Título do post" required /> <textarea name="content" placeholder="Conteúdo do post" required /> <SubmitButton /> </form> ); }'use server'; // Este arquivo contém Server Actions import { revalidatePath } from 'next/cache'; import { redirect } from 'next/navigation'; import prisma from './db'; // Assumindo que você tem o Prisma configurado export async function createPost(formData: FormData) { // TODO: Adicionar validação de dados e autenticação/autorização const title = formData.get('title') as string; const content = formData.get('content') as string; await prisma.post.create({ data: { title, content, authorId: 'clx0p0123456789abcdefghij', // Substitua por ID do usuário logado }, }); revalidatePath('/dashboard'); // Invalida o cache da rota para mostrar o novo post redirect('/dashboard'); // Redireciona o usuário }Este é um exemplo oficial da documentação do Next.js, adaptado para um contexto de postagem. Ele demonstra como um Client Component pode interagir diretamente com uma função de servidor para realizar uma ação.
-
API Routes (
app/api/): Para cenários onde você precisa de um endpoint HTTP tradicional, como integrar com um webhook de terceiros, ou construir uma API REST/GraphQL para clientes que não são Next.js.import { NextResponse } from 'next/server'; import prisma from '@/lib/db'; // Assumindo o Prisma export async function GET() { // TODO: Adicionar autenticação/autorização try { const users = await prisma.user.findMany({ select: { id: true, email: true, name: true, }, }); return NextResponse.json(users); } catch (error) { console.error('Erro ao buscar usuários:', error); return NextResponse.json({ message: 'Erro interno do servidor' }, { status: 500 }); } } export async function POST(request: Request) { // TODO: Adicionar validação de dados e autenticação/autorização const { name, email, password } = await request.json(); try { const newUser = await prisma.user.create({ data: { name, email, password: 'hashed-password', // Em uma aplicação real, hash a senha! }, }); return NextResponse.json(newUser, { status: 201 }); } catch (error) { console.error('Erro ao criar usuário:', error); return NextResponse.json({ message: 'Erro ao criar usuário' }, { status: 500 }); } }Este exemplo mostra como criar endpoints REST para buscar e criar usuários.
2.7. Implantação (Deployment) 🚀
- Vercel: A plataforma recomendada para Next.js, oferece integração perfeita com Server Actions, Server Components e API Routes, além de otimizações de performance.
3. Exercício/Desafio: Planejando Seu Projeto Final 🧠
Agora é a sua vez! Use os conceitos que discutimos para começar a planejar seu próprio projeto final. Não se preocupe em ter todas as respostas, o objetivo é pensar criticamente sobre a estrutura.
Tarefa de Planejamento:
- Defina a Ideia do Projeto: Qual aplicação full stack você gostaria de construir? (Ex: um blog, uma loja virtual simples, um gerenciador de tarefas, um app de notas).
- Liste Requisitos Funcionais: Quais são as 3-5 funcionalidades principais que sua aplicação deve ter?
- Esboce o Modelo de Dados: Quais entidades principais sua aplicação terá e como elas se relacionam? (Ex:
Usertem muitosPosts,Posttem muitosComments). - Escolha as Ferramentas Principais:
- Banco de Dados: SQL (PostgreSQL, SQLite) ou NoSQL (MongoDB)?
- ORM: Prisma?
- Autenticação: NextAuth.js?
- Pense na Estrutura de Pastas: Como você organizaria os arquivos principais dentro de
app/,lib/ecomponents/para as funcionalidades que você listou? - Identifique Server Actions e/ou API Routes: Para quais funcionalidades você usaria Server Actions (mutações) e para quais talvez API Routes (endpoints RESTful)?
Anote suas ideias. Não precisa ser perfeito, apenas um ponto de partida!
4. Resumo e Próximos Passos ✨
Nesta aula, exploramos a importância do planejamento e os elementos chave para estruturar uma aplicação full stack com Next.js 15. Cobrimos desde a definição de requisitos até a escolha de ferramentas e a organização do código para Server Actions e API Routes.
Lembre-se: um bom plano é a fundação para um projeto de sucesso. Dedicar tempo a esta etapa economizará muito esforço no futuro.
Nosso próximo passo será colocar a mão na massa! Começaremos a configurar nosso ambiente de desenvolvimento e a iniciar a estrutura do nosso projeto final, aplicando os conceitos de planejamento que discutimos hoje. Prepare-se para codificar! 💻