Sou Engenheira de Software, atualmente atuando como Fullstack Engineer e baseada em Portugal. Sou uma profissional entusiasmada que ama tecnologia. Trabalho como desenvolvedora web há mais de 15 anos. Ajudo desenvolvedores a melhorar suas habilidades e estou aberta a trocas de conhecimento com qualquer pessoa. Sou mãe de plantas e de dois meninos lindos. Adoro viajar, conhecer novas pessoas e estar em contato com a natureza. O foco e o cuidado com a experiência do usuário são o segredo do sucesso.
Inscreva-se em nossa Newsletter
Fique por dentro de conteúdos, insights e oportunidades do universo tech. Receba novidades e lançamentos direto no seu e-mail.
O Next.js se destaca como uma escolha popular para quem desenvolve web, oferecendo uma solução eficiente para renderização no servidor (SSR) e geração de sites estáticos (SSG). Com o lançamento da versão 14, uma nova funcionalidade tem roubado a cena: Server Actions. Essa característica elimina a necessidade de rotas de API dedicadas, permitindo a execução de código no servidor diretamente do Next.js. Isso abre um leque de possibilidades para as pessoas desenvolvedoras, desde a busca de dados em APIs externas até a manipulação de lógica de negócios complexa, tudo de forma simplificada e integrada.
Este artigo explora o que são Server Actions, como aplicá-las e apresenta casos de usos práticos.
O que são Server Actions?
Imagine que você está em um restaurante e decide pedir um prato que não está no cardápio. Você chama o garçom e faz o pedido. O que acontece nos bastidores você não sabe, mas o garçom, vai até a cozinha e resolve tudo, sem que você precise se preocupar com os detalhes. Se necessário, ele até pode buscar o pedido em outro restaurante, garantindo que você receba o que deseja. Isso é como ir buscar dados em APIs externas, sem afetar a segurança ou performance, pois podemos executar as Server Actions, diretamente sem a necessidade de implementar a camada de servidor para lidar com API. Lembrando que podemos implementar normalmente a camada de servidor e ter API’s, então Server Actions é flexível, onde podemos chamar API interna e externas.
Agora, pense em quando você preenche um formulário em um site. Você clica em enviar e espera que a mensagem chegue ao destino. Essa ação é como enviar uma carta sem precisar ir aos correios. O formulário vai direto para quem precisa, sem passar por intermediários, simplificando todo o processo, ou seja, é como executar lógicas de negócios que necessitam da execução no servidor, como o caso do processamento dos dados do formulário no servidor, mas sem precisar implementar os detalhes desse servidor.
Atualizar um banco de dados sem complicações é como chegar rapidamente ao destino sem a necessidade de fazer todo o roteiro, simplificando toda a operação, ou seja, lidar com a conexão com o banco de dados, de forma segura, os tokens de autorização e demais elementos sensíveis permanecem protegidos no lado do servidor, uma prática comum no desenvolvimento back-end. No entanto, é possível estabelecer essa conexão com banco de dados através das Server Actions que moram no mesmo repositório que nossos componentes React.
As Server Actions do Next.js são como funções de JavaScript assíncronas que operam no servidor em resposta a interações do usuário no cliente. Por exemplo, ao enviar um formulário para salvar um usuário, uma Server Action é acionada. O servidor executa essa ação e retorna a resposta para o Next.js, que a envia de volta para o front-end.
A Sintaxe para Definir Server Actions
Você pode definir Server Actions no próprio componente do servidor ou em arquivos separados para reutilização. Basta adicionar a diretiva "use server" no início da função.
// Server ComponentexportdefaultfunctionServerComponent() {
// Server ActionasyncfunctionminhaAction() {
'use server'// ... implementação
}
return ( … )
}
Ou em um arquivo separado para reutilização, essencialmente elas são funções. Isto significa que podem ser reutilizadas em qualquer parte da sua aplicação, onde podemos utilizar tanto em Client Components, quanto em Server Components.
Como dizem que mar calmo não faz bom marinheiro, então vamos agitar um pouco as coisas. Antes de mais nada, este tutorial começa com um código-base que simula um ambiente real, onde frequentemente nos deparamos com este tipo de situação. Aqui, vamos concentrar-nos nas Server Actions, otimizando nosso tempo ao invés de começarmos do absoluto zero.
Note que estamos associando a esta requisição fetch() uma tag - "User", que irá invalidar o cache. Vamos utilizar essa tag mais tarde, quando quisermos buscar novamente nossos usuários atualizados, após cadastrar um novo usuário no banco de dados.
O código do componente UserList.tsx, agora deve estar assim:
Já temos o componente UserList.tsx fazendo a requisição para o endpoint de users.
Muito bem, agora temos que importá-lo no arquivo app/page.tsx, que é página inicial, além de incluí-lo dentro de <main> o <UserList />. Ficando desta forma:
Vamos aproveitar que estamos aqui e vamos adicionar um <Link> logo acima do componente <UserList /> . Dessa forma, posteriormente, seremos capazes direcionar para a rota que faz a inclusão de um novo usuário:
A aplicação será executada localmente em: http://localhost:3000. O resultado da página deverá ser este:
Já existem alguns usuários salvos no arquivo mockado do nosso banco de dados, que está localizado em: /public/data.json, por isso, foram renderizados alguns usuários na lista.
Formulário criar novo usuário
Vamos avançar mais uma etapa, agora é o momento de ajustar o formulário para criar um novo usuário.
Vamos lançar mão da joia rara, Server Actions! Desta forma, podemos criar um novo usuário no nosso banco de dados!
Vá para o componente UserFormServerSide.tsx, eis que vamos conhecer a anatomia do nosso formulário, existem dois inputs um para o nome(name) e outro para inserir o aniversário(birthday) do usuário, por último mas não menos importante, o botão do tipo submit que faz a mágica acontecer.
Sabendo disto, agora crie um diretório chamado user na raiz do diretório app/, dentro deste diretório user, crie outro diretório com o nome create, e então adicione um arquivo com nome page.tsx.
Muito bem, quando clicarmos no botão cadastrar novo usuário, vamos redirecionar o usuário para a rota que criamos anteriormente: http://localhost:3000/user/create. O resultado desta página deverá ser este:
Adicionando o Server Action
Temos que fazer o post deste formulário para inserir os dados nos bancos de dados. No arquivo UserFormServerSide.tsx, existe uma função chamada addUser() que atua como nosso garçom do lado do servidor, é o Server Action. Ela está marcada com "use server" para garantir que não seja executada no lado do cliente, mantendo nossas operações seguras e eficientes, pois serão executadas na camada de servidor:
A seguir, veja que pegamos os dados enviados do formulário e associamos as variáveis: “name” e “birthday”, em seguida criamos o objeto “newUserBody”.
// Lógica para inserir os dados do form...const name = data.get("name")?.toString();
const birthday = data.get("birthday")?.toString();
const newUserBody = {
name,
birthday,
};
E fazemos o “post” deste objeto para a API user, a fim de salvar os dados no banco de dados.
Depois do novo usuário ser enviado para a nossa base de dados, utilizamos revalidateTag("User") para atualizar os dados, inclusive teremos o novo usuário recém adicionado.
Por fim, navegamos de volta para a página inicial e podemos conferir o novo usuário adicionado!
// Post user para o mock database
await axios.post("http://localhost:3000/api/users", newUserBody);
// Refetch usuáriosrevalidateTag("User");
redirect("/");
No entanto, falta integrar a ação addUser ao formulário e dar vida à nossa aplicação!
Abra o arquivo UserFormServerSide.tsx, onde começa a tag <form>, adicione a action a função do nosso Server Action ‘addUser’:
Se tudo estiver funcionando como esperado, você deve observar o seguinte:
Ao enviar o formulário, você será redirecionado para a rota “/”.
Você poderá visualizar o novo usuário adicionado ao final da lista 🎯
Se você chegou até aqui! Parabéns ⭐️⭐️⭐️⭐️⭐️! Você implementou com êxito sua primeira Server Action!
Vale Lembrar que Server Actions não são limitadas a <form> e podem ser invocadas a partir de manipuladores de eventos, useEffect, bibliotecas de terceiros e outros elementos de formulário, como <button>.
Organizando o Server Action
Vamos organizar nosso Server Action e deixar o componente com uma estrutura mais limpa. No componente UserFormServerSide.tsx, copie a função adduser().
Agora, crie um novo diretório dentro de app/ com o nome actions/ e em seguida crie o arquivo user.ts. Cole a Server Action addUser() para dentro do arquivo user.ts e inclua os imports necessários. Lembre-se de adicionar o “use server” no início do arquivo:
"use server";
import axios from"axios";
import { revalidateTag } from"next/cache";
import { redirect } from"next/navigation";
exportconstaddUser = async (data: FormData) => {
// Logica para inserir os dados do form...const name = data.get("name")?.toString();
const birthday = data.get("birthday")?.toString();
const newUserBody = {
name,
birthday,
};
// Post user para o mock databaseawait axios.post("http://localhost:3000/api/users", newUserBody);
// Refetch User'srevalidateTag("User");
redirect("/");
};
Em seguida volte no arquivo UserFormServerSide.tsx, apague o addUser() e os imports não utilizados, e por fim faça o import do addUser() que acabamos de mover:
Teste novamente no navegador para assegurar que a aplicação continua a funcionar corretamente.
Testando Server Actions em Client Component
Temos o componente UserFormClientSide.tsx, navegue para o arquivo app/user/create/page.tsx, substitua o <UserFormServerSide />, por <UserFormClientSide />, que do qual, é nosso Client Component que contém a lógica para gerenciar dados dos formulário, utilizando useState, que é permitido apenas em Client Components.
E faça o teste, cadastre um novo usuário, onde a submissão do formulário deverá continuar a funcionar corretamente.
Outros casos de usos para Server Actions
As Server Actions podem ser utilizadas em diversos cenários para otimizar nossas aplicações Next.js. Por exemplo:
Autenticação e autorização: Valide as credenciais do usuário e controle o acesso a recursos específicos da aplicação no servidor.
Gerenciamento de dados: Buscar, atualizar e excluir dados de bancos de dados ou APIs de forma segura e eficiente, sem expor informações importantes, como tokens, etc.
Processamento de pagamentos: Implemente transações seguras sem expor informações confidenciais do cliente.
Geração de relatórios e documentos: Crie relatórios dinâmicos e personalizados no servidor.
Integração com API externas: Utilize as Server Actions para uma integração direta com APIs externas, eliminando a necessidade de desenvolver um API route interno. Com essa abordagem, é possível acessar dados de forma direta, ao mesmo tempo em que se mantêm informações críticas protegidas e seguras, realizando todas as operações relevantes no lado do servidor.
Casos de Uso Avançados
API Proxy: Server Actions podem agir como um proxy para APIs externas, ocultando chaves de API e aplicando lógica adicional.
Processamento e agregação de dados de múltiplas APIs: Server Actions podem ser usadas para coletar dados de várias APIs externas, processá-los no servidor e então enviar um conjunto consolidado e otimizado de informações para o cliente. Isso não só melhora a eficiência da transferência de dados ao reduzir o tamanho do payload, mas também permite implementar uma camada de lógica de negócios que pode enriquecer os dados antes de serem exibidos ao usuário. Por exemplo, você poderia ter uma Server Action que consulta APIs de clima, tráfego e notícias, combina todos esses dados em uma resposta consolidada em um dashboard por exemplo, enquanto também realiza cache dessas informações para melhorar a performance.
Customização de respostas de API com base no usuário: Server Actions podem ser configuradas para modificar as respostas de APIs externas com base nas preferências ou no histórico de um usuário. Por exemplo, uma aplicação de um e-commerce poderia usar Server Actions para chamar uma API de produtos e, em seguida, personalizar a lista de produtos com base no histórico de navegação ou compra do usuário, oferecendo uma experiência de usuário mais personalizada.
Existem uma infinidade de casos de usos onde a Server Actions nos ajudam a implementar de forma robusta, eficiente e prática. Com isso, podemos focar na lógica de negócios, em vez de dedicar tempo excessivo ao desenvolvimento de estratégias para gerenciar nossas integrações. Esta abordagem otimiza nosso fluxo de trabalho, garantindo que a atenção esteja voltada para o que realmente importa: agregar valor ao nosso negócio e melhorar a experiência do usuário.
As Server Actions são uma adição poderosa ao Next.js, proporcionando segurança, desempenho e simplicidade. Elas nos permitem focar na lógica de negócios, sem perder tempo com infraestrutura complexa. Experimente e compartilhe suas experiências com essa nova funcionalidade!
Se precisar consultar o código modificado, consulte aqui no Github. Através dessa comparação, você consegue visualizar as alterações específicas entre o projeto base e o projeto finalizado.
Espero que esta introdução às Server Actions tenha sido útil e que você aproveite ao máximo essa nova funcionalidade do Next.js!
Se quiser se aprofundar no assunto
Aqui na Alura, temos vários conteúdos sobre Next, vamos conhecê-las?