Como integrar o MongoDB ao seu aplicativo Next.js
Ado Kukic, Kushagra Kesav11 min read • Published May 12, 2022 • Updated Apr 02, 2024
Avalie esse Tutorial
Este tutorial usa o roteador de páginas do Next.js em vez do roteador de aplicativos introduzido na versão 13 do Next.js. O roteador de páginas ainda é compatível e recomendado para ambientes de produção.
Você está construindo seu próximo aplicativo incrível com Next.js? Gostaria de poder integrar o MongoDB ao seu aplicativo Next.js sem esforço? Precisa fazer isso antes que o café fique pronto? Se você respondeu sim a essas três perguntas, tenho boas notícias para você. Nós criamos uma integração Next.js<>MongoDB que o colocará em funcionamento em minutos, e você pode considerar este tutorial seu guia oficial de como usá-lo.
Neste tutorial, vamos dar uma olhada em como podemos usar o exemplo with-mongodb para criar um novo aplicativo Next.js que segue as melhores práticas do MongoDB para conectividade, monitoramento de pool de conexões e realização de query. Também daremos uma olhada em como usar o MongoDB em nosso aplicativo Next.js com coisas como serverSideProps e APIs. Por fim, daremos uma olhada em como podemos implantar e hospedar facilmente nosso aplicativo no Vercel, a plataforma de hospedagem oficial para aplicativos Next.js. Se você já tem um aplicativo Next.js, não se preocupe. Basta adicionar o arquivo utilitário do MongoDB ao seu projeto existente e você está pronto para começar. Temos muitas coisas interessantes para abordar, então vamos lá!
Nosso aplicativo agora está implantado e em execução na produção. Se você não estava acompanhando o tutorial e só quer iniciar rapidamente seu aplicativo Next.js com o MongoDB, pode usar o starter
with-mongodb
encontrado no GitHub, mas eu tenho um ainda melhor para você.Visite Vercel e você estará pronto para criar e implantar o Next.js oficial com a integração MongoDB, e tudo que você precisa fornecer é sua string de conexão.
Para este tutorial, você precisará de:
- NodeJS 18+.
- npm e npx.
Para aproveitar ao máximo este tutorial, você precisa estar familiarizado com React e Next.js. Abordarei os recursos exclusivos do Next.js com detalhes suficientes para ainda serem valiosos para um novato.
Se você ainda não está familiarizado com ele, o Next.js é um framework baseado no React para a criação de aplicativos web modernos. O framework adiciona muitos recursos avançados – como renderização no lado do servidor, divisão automática de código e restauração estática incremental – que facilitam a criação de aplicativos escaláveis e prontos para produção.
O Next.js tem uma ampla biblioteca de exemplos que mostra como você pode integrar a estrutura com vários recursos, como servidores GraphQL, bibliotecas de autenticação e estruturas CSS. O exemplo que usaremos neste tutorial é chamado with-mongodb e, como você pode esperar, ele vem com tudo o que é necessário para se conectar a um MongoDB database.
Para criar um novo aplicativo Next.js com integração com o MongoDB, execute o seguinte comando no seu terminal:
1 npx create-next-app --example with-mongodb mflix
Estamos usando o comando
npx create-next-app
e estamos passando o parâmetro --example with-mongodb
, que dirá a create-next-app
para inicializar nosso aplicativo com o exemplo de integração do MongoDB. Por fim, mflix
é o nome do nosso aplicativo. Você pode dar outro nome ao aplicativo, se preferir. A execução deste comando levará alguns segundos para baixar e instalar todas as dependências npm, mas depois que elas forem baixadas e instaladas, navegue até o diretório do projeto executando:1 cd mflix
Em seguida, instale todas as dependências do npm executando:
1 npm install
Nesse diretório, vamos iniciar nosso aplicativo e ver o que acontece. Para iniciar nosso aplicativo Next.js, no diretório mflix, execute:
1 npm run dev
Depois que o aplicativo for criado, vamos vê-lo em ação navegando até
localhost:3000
. Uh-oh. Recebemos um erro.A boa noticia é que o erro é bastante descritivo. O motivo desse erro é que não fornecemos nossa string de conexão do MongoDB para o aplicativo Next.js. Vamos fazer isso a seguir.
Se olharmos para o diretório do aplicativo Next.js, encontraremos um arquivo
env.local.example
. Vamos renomear esse arquivo para env.local e abri-lo. Esse arquivo contém uma propriedade que precisaremos preencher: MONGODB_URI
.Obteremos essas informações do nosso MongoDB Atlas cluster. Você pode usar uma instalação local do MongoDB, se tiver uma, mas se estiver apenas começando, o MongoDB Atlas é uma ótima maneira de começar a trabalhar sem precisar instalar ou gerenciar sua instância do MongoDB. O MongoDB Atlas tem uma camada grátis para sempre, na qual você pode se inscrever e obter os dados de amostra que usaremos no restante deste tutorial.
Para obter nosso URI do MongoDB, em nosso painel do MongoDB Atlas:
- Clique no botão Conectar.
- Em seguida, clique no botão Conectar ao seu aplicativo e aqui você verá uma string que contém seu URI que terá a seguinte aparência:
1 mongodb+srv://<USERNAME>:<PASSWORD>@cluster0.<appId>.mongodb.net/<DBNAME>?retryWrites=true&w=majority
Se você for iniciante no MongoDB Atlas, precisará ir até a seção Acesso ao banco de dados e criar um nome de usuário e uma senha, e depois até a aba Acesso à rede para garantir que seu IP tenha permissão para se conectar ao banco de dados. No entanto, se você já tiver um usuário de banco de dados e o acesso à rede ativado, só precisará substituir os campos
<USERNAME>
e <PASSWORD>
pelas suas informações.Para o
<DBNAME>
,carregaremos os conjuntos de dados de amostra do MongoDB Atlas e usaremos um desses bancos de dados.Para fechar esta seção, nosso arquivo
env.local
deve ficar assim:1 MONGODB_URI=mongodb+srv://<USERNAME>:<PASSWORD>@cluster0.tdm0q.mongodb.net/sample_mflix?retryWrites=true&w=majority
Para garantir que nossa configuração esteja correta, vamos reiniciar nosso aplicativo Next.js indo para o terminal e compilando o aplicativo novamente. Execute o seguinte comando no seu terminal:
1 npm run dev
Quando o aplicativo for criado, vá até
localhost:3000
em seu navegador e verá o seguinte:Esta é a página de boas-vindas do aplicativo Next.js
with-mongodb
. Se você vir a mensagem "Você está conectado ao MongoDB", você está pronto. Se você vir a mensagem "Você NÃO está conectado ao MongoDB", verifique sua string de conexão e certifique-se de que o usuário do banco de dados, bem como a conexão de rede, estão definidos corretamente. Se você tiver algum problema, acesse os fóruns da comunidade do MongoDB e ajudaremos a resolvê-los.Agora que estamos conectados ao MongoDB, vamos discutir como podemos consultar os dados do MongoDB e trazê-los para nosso aplicativo Next.js. O Next.js oferece suporte a várias maneiras de obter dados. Podemos criar pontos de extremidade de API, obter dados executando funções renderizadas do lado do servidor para uma página específica e até gerar páginas estáticas obtendo nossos dados no tempo de construção. Veremos os três exemplos.
O primeiro exemplo que veremos é a criação e a exposição de um endpoint de API em nosso aplicativo Next.js. Para criar uma nova rota de endpoint de API, primeiro precisaremos criar um diretório
api
em nosso diretório pages
e, em seguida, cada arquivo que criarmos nesse diretório api
será tratado como um endpoint de API individual.Vamos criar o diretório
api
e um novo arquivo neste directory
chamado movies.tsx
. Esse endpoint retornará uma lista de 20 filmes do nosso MongoDB database. A implementação desta rota é a seguinte:1 import clientPromise from "../../lib/mongodb"; 2 import { NextApiRequest, NextApiResponse } from 'next'; 3 4 export default async (req: NextApiRequest, res: NextApiResponse) => { 5 try { 6 const client = await clientPromise; 7 const db = client.db("sample_mflix"); 8 const movies = await db 9 .collection("movies") 10 .find({}) 11 .sort({ metacritic: -1 }) 12 .limit(10) 13 .toArray(); 14 res.json(movies); 15 } catch (e) { 16 console.error(e); 17 } 18 }
Para explicar o que está acontecendo aqui, começaremos com a declaração de importação. Estamos importando nosso método
clientPromise
do lib/mongodb
. Este arquivo contém todas as instruções sobre como se conectar ao nosso MongoDB Atlas cluster. Além disso, dentro desse arquivo, armazenamos em cache a instância da nossa conexão para que as solicitações subsequentes não precisem se reconectar ao cluster do Atlas. Eles podem usar a conexão existente. Tudo isso já está feito para você!A seguir, nosso manipulador de rotas de API tem a assinatura de
export default async (req, res)
. Se você estiver familiarizado com Express.js, isso vai soar muito familiar. Esta é a função executada quando a rota localhost:3000/api/movies
é chamada. Capturamos a solicitação por meio de req
e retornamos a resposta por meio do objeto res
.Nossa implementação de função de manipulador chama a função
clientPromise
para obter a instância do nosso MongoDB database. Em seguida, executamos uma query do MongoDB usando o driver Node.js do MongoDB para obter os 20 principais filmes de nossa coleção de filmes com base em sua classificação metacrítica classificada em ordem decrescente.Por fim, chamamos o método
res.json
e passamos nossa array de filmes. Isso entrega nossos filmes no formato JSON para o navegador. Se navegarmos para localhost:3000/api/movies
, veremos um resultado parecido com este:Podemos adicionar outras rotas de API criando arquivos adicionais no diretório
api
. Como exercício de casa, por que você não cria uma rota de API que retorna um único filme com base em uma ID fornecida pelo usuário?Para fornecer algumas indicações, você usará Next.js API para capturar o
id
. Então, se um usuário ligar para http://localhost:3000/api/movies/573a1394f29313caabcdfa3e
, o filme que deve ser devolvido é Seven Samurai. Outra dica: a propriedade _id
do banco de dados sample_mflix
no MongoDB é armazenada como um ObjectId, portanto, você terá que converter a string em um ObjectId. Se você tiver dificuldade, crie um tópico nos fóruns da MongoDB Community e podemos encontrar uma solução juntos! Em seguida, vejamos como acessar nossos dados do MongoDB em nossas páginas Next.js.Na última seção, vimos como podemos criar um endpoint de API e nos conectar ao MongoDB com ele. Nesta seção, obteremos nossos dados diretamente em nossas páginas Next.js. Faremos isso usando o método getServerSideProps() que está disponível para páginas Next.js.
O método
getServerSideProps()
força uma página Next.js a ser carregada com a renderização do lado do servidor. O que isso significa é que toda vez que essa página é carregada, o método getServerSideProps()
é executado no backend, obtém dados e os envia para o componente React por meio de acessórios. O código em getServerSideProps()
nunca é enviado ao cliente. Isso o torna um ótimo lugar para implementar nossas queries do MongoDB.Vejamos como isso funciona na prática. Vamos criar um novo arquivo no diretório
pages
e chamá-lo de movies.tsx
. Neste arquivo, adicionaremos o seguinte código:1 import clientPromise from "../lib/mongodb"; 2 import { GetServerSideProps } from 'next'; 3 4 5 interface Movie { 6 _id: string; 7 title: string; 8 metacritic: number; 9 plot: string; 10 } 11 12 13 interface MoviesProps { 14 movies: Movie[]; 15 } 16 17 18 const Movies: React.FC<MoviesProps> = ({ movies }) => { 19 return ( 20 <div> 21 <h1>Top 20 Movies of All Time</h1> 22 <p> 23 <small>(According to Metacritic)</small> 24 </p> 25 <ul> 26 {movies.map((movie) => ( 27 <li key={movie._id}> 28 <h2>{movie.title}</h2> 29 <h3>{movie.metacritic}</h3> 30 <p>{movie.plot}</p> 31 </li> 32 ))} 33 </ul> 34 </div> 35 ); 36 }; 37 38 39 export default Movies; 40 41 42 export const getServerSideProps: GetServerSideProps = async () => { 43 try { 44 const client = await clientPromise; 45 const db = client.db("sample_mflix"); 46 const movies = await db 47 .collection("movies") 48 .find({}) 49 .sort({ metacritic: -1 }) 50 .limit(20) 51 .toArray(); 52 return { 53 props: { movies: JSON.parse(JSON.stringify(movies)) }, 54 }; 55 } catch (e) { 56 console.error(e); 57 return { props: { movies: [] } }; 58 } 59 };
Como você pode ver no exemplo acima, estamos importando a mesma classe de utilitário
clientPromise
e nossa query do MongoDB é exatamente a mesma do método getServerSideProps()
. A única coisa que realmente precisamos mudar em nossa implementação é como analisamos a resposta. Precisamos fazer stringify e, em seguida, analisar manualmente os dados, pois o Next.js é rigoroso.Nosso componente de página chamado
Movies
obtém os props de nosso método getServerSideProps()
e usamos esses dados para renderizar a página que mostra o título do filme principal, a classificação metacrítica e o enredo. Seu resultado deve ser semelhante a este:Isso é ótimo. Podemos consultar diretamente nosso MongoDB database e obter todos os dados de que precisamos para uma determinada página. O conteúdo do método
getServerSideProps()
nunca é enviado ao cliente, mas a única desvantagem disso é que esse método é executado toda vez que chamamos a página. Nossos dados são bastante estáticos e é improvável que mudem com tanta frequência. E se fizéssemos uma pré-renderização dessa página e não precisássemos chamar o MongoDB a cada atualização? Veremos isso a seguir!Para nosso exemplo final, veremos como a geração de página estática pode funcionar com o MongoDB. Vamos criar um novo arquivo no diretório
pages
e chamá-lo de top.tsx
. Nesta página, o que queremos fazer é renderizar os 1.000 principais filmes do nosso MongoDB database.Top 1.000 filmes? Você está louco? Isso vai demorar um pouco e a viagem de ida e volta ao banco de dados não vale a pena. Bem, e se chamarmos esse método apenas uma vez quando criamos o aplicativo, de modo que, mesmo que a chamada demore alguns segundos, ela acontecerá apenas uma vez e nossos usuários não serão afetados? Eles receberão os melhores 1.000 filmes com a mesma rapidez ou até mais rápido do que receberiam 20, usando
serverSideProps()
. A mágica está no método getStaticProps()
e nossa implementação é assim:1 import { ObjectId } from "mongodb"; 2 import clientPromise from "../lib/mongodb"; 3 import { GetStaticProps } from "next"; 4 5 6 interface Movie { 7 _id: ObjectId; 8 title: string; 9 metacritic: number; 10 plot: string; 11 } 12 13 14 interface TopProps { 15 movies: Movie[]; 16 } 17 18 19 export default function Top({ movies }: TopProps) { 20 return ( 21 <div> 22 <h1>Top 1000 Movies of All Time</h1> 23 <p> 24 <small>(According to Metacritic)</small> 25 </p> 26 <ul> 27 {movies.map((movie) => ( 28 <li key={movie._id.toString()}> 29 <h2>{movie.title}</h2> 30 <h3>{movie.metacritic}</h3> 31 <p>{movie.plot}</p> 32 </li> 33 ))} 34 </ul> 35 </div> 36 ); 37 } 38 39 40 export const getStaticProps: GetStaticProps<TopProps> = async () => { 41 try { 42 const client = await clientPromise; 43 44 45 const db = client.db("sample_mflix"); 46 47 48 const movies = await db 49 .collection("movies") 50 .find({}) 51 .sort({ metacritic: -1 }) 52 .limit(1000) 53 .toArray(); 54 55 56 return { 57 props: { movies: JSON.parse(JSON.stringify(movies)) }, 58 }; 59 } catch (e) { 60 console.error(e); 61 return { 62 props: { movies: [] }, 63 }; 64 } 65 };
À primeira vista, isso parece muito semelhante ao arquivo
movies.tsx
que criamos anteriormente. As únicas alterações significativas que fizemos foram mudar nosso limit
de 20
para 1000
e nosso método getServerSideProps()
para getStaticProps()
. Se navegarmos até localhost:3000/top
em nosso navegador, veremos uma longa lista de filmes.Veja como essa barra de rolagem é pequena. O carregamento desta página demorou cerca de 3,79 segundos na minha máquina, em oposição ao tempo de resposta de 981 milissegundos para a página
/movies
. A razão pela qual demora tanto é que, no modo de desenvolvimento, o método getStaticProps()
é chamado toda vez (assim como o método getServerSideProps()
). Mas se mudarmos do modo de desenvolvimento para o modo de produção, veremos o oposto. A página /top
será pré-renderizada e carregada quase imediatamente, enquanto as rotas /movies
e /api/movies
executarão o código do lado do servidor todas as vezes .Vamos mudar para o modo de produção. Na janela do terminal, interrompa a execução do aplicativo atual. Para executar nosso aplicativo Next.js no modo de produção, primeiro precisamos criá-lo. Em seguida, podemos executar o comando
start
que atenderá ao nosso aplicativo criado. Em sua janela de terminal, execute os seguintes comandos:1 npm run build 2 npm run start
Quando você executa o comando
npm run start
, seu aplicativo Next.js é servido no modo de produção. O método getStaticProps()
não será executado toda vez que você atingir a rota /top
, pois esta página agora será servida estaticamente. Podemos até ver a página estática pré-renderizada navegando até o arquivo .next/server/pages/top.html
e vendo os 1.000 filmes listados em HTML simples.Next.js pode até atualizar esse conteúdo estático sem exigir uma reconstrução com um recurso chamado Regeneração estática incremental, mas isso está fora do escopo deste tutorial. A seguir, daremos uma olhada na implantação de nosso aplicativo no Vercel.
A etapa final do nosso tutorial de hoje é implantar o aplicativo. Implantaremos nosso aplicativo Next.js com MongoDB no Vercel. Criei um repositório do GitHub que contém todo o código que escrevemos hoje. Fique à vontade para clonar ou criar o seu.
Navegue até Vercel e faça login. Quando estiver no painel, clique no botão Importar Projeto e, em seguida, em Importar Repositório Git.
O URL que usarei é o fornecido acima que tem o aplicativo que criamos hoje. Para referência, esse URL é
https://github.com/mongodb-developer/nextjs-with-mongodb
. Adicione o URL do GitHub dos seus projetos e clique em Continuar. Na próxima tela, você terá a opção de adicionar Variáveis de ambiente. Aqui, adicionaremos as variáveis do nosso arquivo env.local
.Depois de pressionar o botão Implantar, seu aplicativo Next.js será automaticamente criado e implantado. Esse processo levará alguns minutos, mas, uma vez concluído, você receberá um URL no qual poderá acessar o aplicativo Next.js.
NOTA: o Vercel utiliza endereços IP dinâmicos, então você precisará adicionar uma exceção para acessar de qualquer endereço IP no dashboard do MongoDB Atlas. Para fazer isso, basta navegar até a aba Acesso à Rede, clicar no botão Adicionar Endereço IP e, em seguida, clicar no botão Permitir acesso de qualquer lugar ou, para a Entrada da lista de acesso, inserir 0.0.0.0/0.
Estamos operacionais! Para confirmar que tudo está funcionando, navegamos até https://nextjs-with-mongodb-mauve.vercel.app/movies, https://nextjs-with-mongodb-mauve.vercel.app/api/movies e https: //nextjs-with-mongodb-mauve.vercel.app/top routes.
Neste tutorial, analisamos o exemplo oficial do Next.js com MongoDB. Mostrei como conectar seu MongoDB database ao seu aplicativo Next.js e executar queries de várias maneiras. Em seguida, implementamos nosso aplicativo usando o Vercel.
Se você tiver alguma dúvida ou feedback, entre em contato através dos Fóruns da MongoDB Community e me conte o que você criou com o Next.js e com o MongoDB.