Explore o novo chatbot do Developer Center! O MongoDB AI chatbot pode ser acessado na parte superior da sua navegação para responder a todas as suas perguntas sobre o MongoDB .

Junte-se a nós no Amazon Web Services re:Invent 2024! Saiba como usar o MongoDB para casos de uso de AI .
Desenvolvedor do MongoDB
Central de desenvolvedor do MongoDBchevron-right
Idiomaschevron-right
JavaScriptchevron-right

Introdução ao Bun e ao MongoDB

Joel Lord9 min read • Published Jul 19, 2024 • Updated Jul 19, 2024
Node.jsTypeScriptJavaScript
Ícone do FacebookÍcone do Twitterícone do linkedin
Avalie esse Início rápido
star-empty
star-empty
star-empty
star-empty
star-empty
O JavaScript percorreu um longo caminho desde sua criação nos 1990s. Agora é muito mais do que uma linguagem de programação de front-end usada para criar efeitos sofisticados em uma página da web. Ele desenvolveu e agora é uma linguagem de back-end de nível empresarial com o Node.js.
Nos últimos anos, existiram algumas alternativas para usar JavaScript backend. Além do Node.js, tempos de execução como o Deno visam corrigir alguns dos problemas que os engenheiros têm com o JavaScript.
Este artigo se concentrará no Bun, um tempo de execução de nova geração para executar JavaScript ou TypeScript em um servidor.
Bun é um novo tempo de execução projetado para velocidade. Ele é otimizado para servidores da Web de grande escala e inclui ferramentas modernas, como um interpretador TypeScript integrado, um executor de testes e um gerenciador de pacotes.
É totalmente compatível com o Node.js, e os pacotes que você usa com seus outros projetos também devem funcionar com o Bun.
Neste início rápido, mostraremos como usar o Bun para escrever uma API CRUD simples para ler e escrever em uma collection do MongoDB. Este guia simples usa os pacotes integrados do Bun para criar um servidor web e o driver MongoDB Node.js para se conectar ao banco de dados.

Pré-requisitos

  • Bun: Instale o Bun seguindo as instruções no site.
  • MongoDB: use sua própria instância do MongoDB ou crie um Atlas cluster gratuito para sempre
  • (Opcional) Conjunto de dados de amostra: Se quiser começar com alguns dados, você pode importar o conjunto de dados de amostra para o seu Atlas cluster gratuito

TLDR

Se você quiser começar com um modelo MongoDB e Bun, você pode executar os seguintes comandos.
1git clone https://github.com/mongodb-developer/bun-with-mongodb
2cd bun-with-mongodb
3bun i
4echo "MONGODB_URI=<your_atlas_connection_string>" > .env
5bun run index.ts

Configurar

Como em um projeto típico do Node.js, você precisará começar inicializando seu aplicativo. Isso criará os andaimes necessários para seu aplicativo.
Manteremos nosso projeto muito simples para este tutorial e usaremos o servidor da web Bun.serveintegrado. A única dependência necessária é o pacotemongodb do npm.
Em uma nova pasta, execute os seguintes comandos para inicializar seu projeto e instalar as dependências necessárias.
1bun init
2bun add mongodb
Se você observar os arquivos em sua pasta, agora deverá ver um arquivoindex.ts, junto com as dependências instaladas na pastanode_modules . Se você é um desenvolvedor do Node.js, isso deve parecer muito familiar.

Estrutura do aplicativo

Nosso aplicativo será uma API simples com cinco rotas básicas.
  • POST /movies: Pegará um filme no corpo e o inserirá na collection
  • GET /movies: recupera os últimos 10 filmes que foram adicionados ao banco de dados
  • GET /movies/:id: Retorna um único filme por id
  • PUT /movies/:id: Atualiza o filme especificado no caminho com o corpo
  • DELETE /movies/:id: Exclui o filme especificado no caminho
Todas as rotas serão tratadas no arquivoindex.tsprincipal . A lógica para se conectar ao banco de dados está localizada no arquivoutils/db.ts, e todas as ações executadas no banco de dados podem ser encontradas no arquivocontollers/movies.ts.

Iniciando o aplicativo

Vamos começar com um servidor Web básico. O Bun tem vários pacotes incorporados, incluindo Bun.serve. Esse pacote contém todos os componentes necessários para criar um servidor Web básico.
Substitua o conteúdo do arquivo index.ts pelo seguinte código:
1const server = Bun.serve({
2  async fetch(req) {
3    const url = new URL(req.url);
4    const method = req.method;
5    if (url.pathname === "/") return new Response("Welcome to the movie database");
6    return new Response("404!");
7  },
8});
9console.log(`Listening on http://localhost:${server.port} ...`);
Agora, inicie o aplicativo com o seguinte comando.
1bun --watch run index.ts
Usar --watch recarregará automaticamente o servidor sempre que um arquivo for alterado. Isso é muito conveniente enquanto você está no modo de desenvolvimento.
Por padrão, o Bun usará a porta 3000 com Bun.serve. Você pode alterar isso definindo a variável de ambientePORTdo seu shell. O Bun usará automaticamente a porta definida nessa variável de ambiente.
Para testá-lo, use o Postman ou um serviço semelhante, seu navegador da Web ou uma ferramenta CLI, como o curl. Para este artigo, usarei curl.
Execute o seguinte comando em uma nova janela de terminal para testar seu aplicativo.
1curl localhost:3000
Você deve ver uma mensagem dizendo Bem-vindo ao banco de dados de filmes.
Parabéns! Você criou com sucesso um servidor da web com o Bun — hora de se conectar a um MongoDB database.

Conectando ao MongoDB

A conexão com o MongoDB database será tratada por um arquivo chamado utils/db.ts. Aqui, você usará o MongoDB (já instalado com o bun add) para criar um MongoClient. Em seguida, você se conectará à coleçãomovies e exportará essa coleção para seus comandos usarem.
Em um ambiente de produção, você também adicionaria alguma lógica para garantir que a conexão com o banco de dados esteja funcionando corretamente, mas, para os fins deste artigo, vamos nos ater ao básico.
Comece com um novo arquivo chamado utils/db.ts.
1import { MongoClient } from "mongodb";
2let MONGODB_URI = process.env.MONGODB_URI;
3if (!MONGODB_URI) {
4  throw new Error("Please define the MONGODB_URI environment variable inside .env");
5}
6
7const client: MongoClient = await MongoClient.connect(MONGODB_URI);
8const moviesCollection = client.db("sample_mflix").collection("movies");
9
10export {
11  moviesCollection
12}
Você notará que a string de conexão para MongoDB (MONGODB_URI) é lida diretamente das variáveis de ambiente. Com o Bun, não há necessidade de usar um pacote para injetar essas variáveis em seu aplicativo. Ele será lido automaticamente do seu arquivo.env.
Então, vamos em frente e crie um arquivo.env na pasta raiz do seu projeto.
1MONGODB_URI=<your_atlas_connection_string>
Substitua o valor da variável de ambiente pela sua string de conexão.
ótimo trabalho! Agora você pode se conectar ao banco de dados. O código não é invocado em lugar nenhum, portanto não há muito para testar. Vejamos como podemos usar essa collection para realizar operações CRUD.

Construindo um modelo de filme

Bun usa o TypeScript pronto para usar. Você também pode optar por usar JavaScript simples, mas como estamos aproveitando o TS para esse aplicativo, precisaremos criar um modelo de filme para informar ao nosso aplicativo como é um filme. Para esse início rápido, nossos filmes terão apenas um título, alguns atores e o ano em que foram lançados.
Criar um arquivomodels/movies.ts:
1import type { ObjectId } from "mongodb";
2
3// Create a custom type for our movies
4export interface Movie {
5  _id?: ObjectId,
6  title: string,
7  actors: string[],
8  year?: number,
9}
Observe como também estamos usando o tipo ObjectId nativo do MongoDB aqui para o campo_id.
Como o MongoDB é um banco de dados, seus documentos podem conter muitas propriedades diferentes, incluindo arrays de strings, como fizemos neste exemplo. Estamos mantendo as coisas simples aqui, mas podem ser objetos ainda mais complexos, como uma array de objetos atores. Você pode descobrir mais sobre o document model na MongoDB University.
Agora que você tem seu modelo, você pode criar seu controlador de filmes.

Criar um controlador de filmes

Você tem um cliente conectado ao seu banco de dados e um modelo que gerencia o formato dos seus dados. Agora é hora de fazer essas operações CRUD no seu banco de dados.
Essas operações são todas tratadas no controlador de filmes. Esse controlador se comunica com o banco de dados e retorna o resultado da operação ao nosso servidor.
Crie um novo arquivo chamado controllers/movies.ts
1// Import the Movies collection
2import { moviesCollection } from '../utils/db.ts';
3// Import the necessary types
4import type { ObjectId } from "mongodb";
5import type { Movie } from "../models/movies.ts";
6
7class MovieController {
8  /**
9   * CRUD operations for the movies collection
10   */
11
12  // Add a movie
13  public async addMovie(movie: Movie) {
14    return await moviesCollection.insertOne(movie);
15  }
16
17  // Fetch the latest ten movies
18  public async getMovies() {
19    return await moviesCollection.find({}).sort({_id: -1}).limit(10).toArray();
20  }
21
22  // Fetch one movie
23  public async getMovieById(_id: ObjectId) {
24    return await moviesCollection.findOne({_id});
25  }
26
27  // Update the movies
28  public async updateMovie(_id: ObjectId, movie: Movie) {
29    return await moviesCollection.updateOne({ _id }, { $set: movie });
30  }
31
32  // Delete a single movie
33  public async deleteMovie(movieId: ObjectId) {
34    return await moviesCollection.deleteOne({ _id: movieId });
35  }
36}
37
38export default MovieController;
Este controlador lista as operações mais básicas que podem ser executadas no banco de dados. Se você quiser saber mais sobre essas operações, recomendamos o Tutorial do MongoDB e Node.js - Operações CRUD na Central do Desenvolvedor. Você também pode consultar nossos Docs para os métodosfind, findOne, insertOne, updateOnee deleteOne de nosso driver em nossos Docs.
Se você precisar de operações mais avançadas, como agrupamento ou facet, também deverá consultar a estrutura de agregação do MongoDB.
Agora que você tem todo o código para executar as operações CRUD na sua collection, é hora de retornar ao servidor e começar com o roteamento da solicitação.

Roteamento de servidor

Agora é hora de unir tudo em nosso arquivoindex.ts, que é o código do próprio servidor. Nesse arquivo, importaremos os componentes necessários, executaremos algum roteamento e chamaremos os métodos apropriados do nosso controlador.
Primeiro, importe os arquivos necessários na parte superior do arquivoindex.ts.
1// Import the Movies functions
2import { ObjectId } from "mongodb";
3import MovieController from "./controllers/movies.ts";
4import type { Movie } from "./models/movies.ts";
Isso importará o controlador de filme que criamos anteriormente e os tipos necessários que usaremos.
Em seguida, reescreva sua lógicaBun.servepara dar suporte a várias rotas.
1const server = Bun.serve({
2  async fetch(req) {
3    const url = new URL(req.url);
4    const method = req.method;
5    if (url.pathname === "/") return new Response("Welcome to the movie database");
6
7    // Routes for the API
8    let moviesRoutes = new RegExp(/^\/movies\/?(.*)/)
9    const movies = new MovieController();
10
11    // POST /movies
12    if (url.pathname.match(moviesRoutes) && method === "POST") {
13      return new Response("Not implemented yet!");
14    }
15
16    // GET /movies and GET /movies/:id
17    if (url.pathname.match(moviesRoutes) && method === "GET") {
18      return new Response("Not implemented yet!");
19    }
20
21    // PUT /movies/:id
22    if (url.pathname.match(moviesRoutes) && method === "PUT") {
23      return new Response("Not implemented yet!");
24    }
25
26    // DELETE /movies/:id
27
28    if (url.pathname.match(moviesRoutes) && method === "DELETE") {
29      return new Response("Not implemented yet!");
30    }
31
32    return new Response("404!");
33  },
34});
Precisamos implementar um sistema de roteamento completo porque não usamos nenhuma framework aqui. Em um ambiente de produção, você provavelmente usaria uma framework como Hono ou Express para ajudá-lo com isso.
Nesse caso, escrevemos uma expressão regular que corresponde a qualquer rota que comece com /movies. Também examinamos o método enviado na solicitação. Se a rota não corresponder a uma das rotas de controle ou começar com /movies, retornaremos a mensagem 404!.
Você pode testar essas rotas usando curl.
1curl localhost:3000/movies
2curl localhost:3000/movies -X POST
3curl localhost:3000/movies -X PUT
4curl localhost:3000/movies -X DELETE
5curl localhost:3000/movies -X PATCH # 404!
Agora é a hora de conectar seu servidor ao seu banco de dados.

Conectando tudo

Podemos finalmente colocar tudo junto.

Adicione um filme

Para adicionar um filme ao banco de dados, você deve ler o corpo da solicitação usando req.json() e enviar esse filme para o seu controlador.
1    // POST /movies
2    if (url.pathname.match(moviesRoutes) && method === "POST") {
3      const movie: Movie = await req.json();
4      return Response.json(await movies.addMovie(movie));
5    }
Aqui, estamos supondo que a solicitação sempre corresponda a um objeto de filme, mas, na realidade, você deseja validar isso. É provável que você também queira tratar quaisquer erros ao inserir os dados.
Depois que o código estiver pronto, você poderá adicionar um novo filme à coleção.
1curl localhost:3000/movies -X POST --data '{"title": "New Movie"}'
Você verá uma confirmação de que a operação funcionou e receberá o novo insertedId.

Ler filmes

Nossa rotaGET /movies é um pouco mais complexa, pois lidará com/movies para recuperar uma lista de filmes 10 e /movies/:id para recuperar um único filme. Para descobrir qual usar, procuraremos a existência de um parâmetro após o componente/movies.
Se estiver lá, pegaremos essa string e a converteremos para um ObjectId antes de enviá-la para o controlador de filmes. Se o parâmetro não estiver lá, usamos o métodogetMovies do controlador de filmes para retornar o 10 mais recente.
1    // GET /movies and GET /movies/:id
2    if (url.pathname.match(moviesRoutes) && method === "GET") {
3      const routeParams = url.pathname.split("/");
4      if (routeParams[2]) {
5        const movieId: ObjectId = new ObjectId(routeParams[2]);
6        return Response.json(await movies.getMovieById(movieId));
7      } else {
8        return Response.json(await movies.getMovies());
9      }
10    }
Agora você pode testar essas novas rotas. Observe que você precisará alterar a rota do segundo comando curl para corresponder a um ObjectId da sua coleção de filmes existente.
1curl localhost:3000/movies
2curl localhost:3000/movies/668e855f76f86976e4045ae9

Atualizar filmes

Usamos o mesmo truque para atualizar um filme para localizar o parâmetro id e convertê-lo em um ObjectId. Em seguida, passamos o corpo da solicitação para o método de atualização do nosso controlador de filmes.
1    // PUT /movies/:id
2    if (url.pathname.match(moviesRoutes) && method === "PUT") {
3      const movieId: ObjectId = new ObjectId(url.pathname.split("/")[2]);
4      const movie: Movie = await req.json();
5      return Response.json(await movies.updateMovie(movieId, movie));
6    }

Excluir filmes

Por fim, para excluir um filme, extraímos o ID do filme do nome do caminho e o passamos para a função de exclusão do nosso controlador de filme.
1    // DELETE /movies/:id
2    if (url.pathname.match(moviesRoutes) && method === "DELETE") {
3      const movieId: ObjectId = new ObjectId(url.pathname.split("/")[2]);
4      return Response.json(await movies.deleteMovie(movieId));
5    }

O que vem a seguir?

É isso ai! Você tem um servidor totalmente funcional em execução no Bun que pode se conectar à sua MongoDB collection e executar operações CRUD básicas. Você pode encontrar todo o código em nosso repositório doGithub .
Para implantar esse código na produção, você deve adicionar mais robustez ao seu código. Você também precisaria tratar os erros e retornar os códigos de erro apropriados quando um documento não for encontrado. Mas este é um bom ponto de partida para seu primeiro aplicativo.
Se tiver alguma dúvida, registre-se em nossos fóruns da comunidade e use o formulário abaixo para entrar em contato conosco!
Principais comentários nos fóruns
Ainda não há comentários sobre este artigo.
Iniciar a conversa

Ícone do FacebookÍcone do Twitterícone do linkedin
Avalie esse Início rápido
star-empty
star-empty
star-empty
star-empty
star-empty
Relacionado
Tutorial

Trabalhando com MongoDB Charts e o novo SDK para JavaScript


Apr 02, 2024 | 10 min read
Tutorial

Use o MongoDB como o armazenamento de dados para seu CMS Strapi Headless


Sep 23, 2022 | 8 min read
Tutorial

Como enviar alterações de documentos do MongoDB para um canal do Slack


Oct 26, 2023 | 6 min read
exemplo de código

GroupUs


Jul 07, 2022 | 1 min read
Sumário