Make the MongoDB docs better! We value your opinion. Share your feedback for a chance to win $100.
MongoDB Branding Shape
Click here >
Docs Menu

Compile una aplicación resiliente con MongoDB Atlas

Al crear una aplicación de misión crítica, es importante prepararse para eventos inesperados que puedan ocurrir en producción. Esto incluye queries lentas inesperadas, índices faltantes o un aumento brusco de la carga de trabajo.

MongoDB Atlas le ayuda a crear una aplicación resiliente al equiparle con funciones listas para usar que le permiten prepararse proactivamente y responder de forma reactiva ante cualquier situación. Para crear una aplicación resiliente, le recomendamos configurar su implementación de MongoDB con las siguientes prácticas recomendadas de resiliencia de clúster y de aplicación y del lado del cliente.

Para mejorar la resiliencia de su clúster, actualice su clúster a MongoDB 8.0. MongoDB 8.0 introduce las siguientes mejoras de rendimiento y nuevas funcionalidades relacionadas con la resiliencia:

Para ejecutar su aplicación de forma segura en producción, es importante asegurarse de que la utilización de memoria permita un margen de maniobra. Si un nodo se queda sin memoria disponible, puede verse afectado por el Linux Out of Memory Killer, que termina el proceso mongod.

MongoDB 8.0 utiliza un TCMalloc actualizado para todas las implementaciones de forma automática, lo que reduce el crecimiento promedio de la fragmentación de memoria con el tiempo. Esta menor fragmentación mejora la estabilidad operativa durante picos de carga y se traduce en una utilización de memoria mejorada en general.

Una operación intensiva en recursos no intencionada puede causar problemas en producción si no se gestiona a tiempo.

MongoDB 8.0 te permite minimizar el impacto de estas operaciones utilizando filtros de rechazo de operaciones. Los filtros de rechazo de operación te permiten configurar MongoDB para rechazar las query hasta que vuelvas a habilitar las query con esa forma del query.

En otras palabras, una vez que identifiques una query lenta, no necesitas esperar a que los equipos de aplicaciones arreglen sus queries para contener el impacto de la query lenta. En su lugar, una vez que detectes un query de bajo rendimiento en tu perfilador del query, Panel de rendimiento en tiempo real o en los registros de query, puedes establecer un filtro de rechazo en esa forma del query. MongoDB luego impide que nuevas instancias de esa forma del query entrante se ejecuten. Una vez que corrijas la query, puedes volver a habilitar la forma del query.

Debes utilizar un filtro de rechazo de operaciones si deseas:

  • Contenga el impacto de las consultas lentas rápidamente mientras se está trabajando en la solución.

  • Prioriza cargas de trabajo más importantes durante tiempos de sobrecarga rechazando queries menos importantes.

  • Dale tiempo al clúster para recuperarse si está cerca del máximo uso de recursos.

Para usar un filtro de rechazo de operaciones en la Interfaz de Usuario de Atlas:

1
  1. Si aún no se muestra, seleccione la organización que contiene su proyecto deseado en el menú Organizations de la barra de navegación.

  2. Si aún no aparece, selecciona el proyecto deseado en el menú Projects de la barra de navegación.

  3. En la barra lateral, haz clic en Clusters en la sección Database.

La página de clústeres se muestra.

2
  1. Haz clic en el nombre del clúster para abrir la barra lateral Cluster.

  2. Haz clic en Query Insights en la barra lateral de Cluster.

  3. Haz clic en la pestaña Query Profiler.

3
4

En los detalles en el lado derecho, copia el valor de queryShapeHash.

5

Usa setQuerySettings en tu método db.adminCommand() para pasar el queryShapeHash, que especifica la forma del query que deseas rechazar.

Nota

Debes tener el rol de atlasAdmin para usar setQuerySettings.

Para ver un ejemplo, consulte Bloquear queries lentas con filtros de rechazo de operaciones.

Puedes supervisar cómo se ejecutan tus queries posteriormente en Métricas en la barra lateral del clúster:

1
  1. Si aún no se muestra, seleccione la organización que contiene su proyecto deseado en el menú Organizations de la barra de navegación.

  2. Si aún no aparece, selecciona el proyecto deseado en el menú Projects de la barra de navegación.

  3. En la barra lateral, haz clic en Clusters en la sección Database.

La página de clústeres se muestra.

2
  1. Haz clic en el nombre del clúster para abrir la barra lateral Cluster.

  2. Haga clic en Metrics.

3

En Shard Name, haz clic en la partición que deseas supervisar.

4

En MongoDB Metrics, haz clic en Operation Throttling.

Con esta métrica, la gráfica de MongoDB muestra lo siguiente:

Es importante asegurarse de que su proceso de desarrollo considere cuidadosamente la eficiencia de las queries antes de que lleguen a producción. Las excepciones pueden ocurrir siempre, pero tener una mitigación proactiva contra queries ineficientes puede ayudar a evitar problemas de rendimiento del clúster.

Con MongoDB 8.0, puedes proteger tus consultas de operaciones no indexadas con el defaultMaxTimeMS del lado del servidor que ingresa al clúster. Si una operación excede este tiempo de espera, MongoDB cancela la operación para evitar que las consultas se ejecuten durante demasiado tiempo y consuman recursos. Esto te permite:

  • Traslada la responsabilidad de establecer límites de tiempo de los equipos de aplicaciones individuales a los equipos enfocados en bases de datos.

  • Minimiza el impacto de un escaneo de colección si a la query le falta un índice.

  • Ten una última ronda de mitigación contra operaciones costosas que lleguen a producción.

Si tienes queries que requieren un tiempo de espera diferente, como las queries de análisis, puedes sobrescribirlas configurando el tiempo de espera a nivel de operación con el método maxTimeMS.

Para establecer el parámetro defaultMaxTimeMS a través de la API de Administración de Atlas, consulta Actualizar opciones avanzadas de configuración para un clúster.

Para establecer el parámetro defaultMaxTimeMS en la interfaz de usuario de Atlas:

1
  1. Si aún no se muestra, seleccione la organización que contiene su proyecto deseado en el menú Organizations de la barra de navegación.

  2. Si aún no aparece, selecciona el proyecto deseado en el menú Projects de la barra de navegación.

  3. En la barra lateral, haz clic en Clusters en la sección Database.

La página de clústeres se muestra.

2
  1. Si tienes un clúster existente, navega a la página Editar clúster.

    Si está creando un nuevo clúster, en la lista desplegable Select a version, seleccione MongoDB 8.0.

  2. Haga clic en Additional Settings.

  3. Desplázate hacia abajo y haz clic en More Configuration Options.

3
4
5
  1. Haga clic en Review Changes.

  2. Se deben revisar los cambios y luego se debe hacer clic en Apply Changes para actualizar el clúster.

Para ver el comportamiento de las operaciones finalizadas,consulte "Supervisar las consultas tras el rechazo o el tiempo de espera". Para obtener más información, consulte defaultMaxTimeMS y "Establecer el tiempo de espera predeterminado para las operaciones de lectura".

Particionado permite escalar tu clúster horizontalmente. Con MongoDB, puedes fragmentar algunas colecciones, mientras permites que otras colecciones en el mismo clúster permanezcan sin fragmentar. Cuando se crea una nueva base de datos, la partición del clúster con la menor cantidad de datos se selecciona como partición primaria de esa base de datos por defecto. Todas las colecciones no particionadas de esa base de datos se encuentran en esa partición primaria por defecto. Esto puede causar un aumento del tráfico en la partición primaria a medida que aumenta la carga de trabajo, especialmente si el crecimiento de la carga de trabajo se centra en las colecciones no particionadas de la partición primaria.

Para distribuir mejor esta carga de trabajo, MongoDB 8.0 permite mover una colección no particionada a otras particiones desde la partición primaria mediante el comando moveCollection. Esto permite ubicar colecciones activas y ocupadas en particiones con un menor uso esperado de recursos. Con esto, puedes:

  • Optimiza el rendimiento en cargas de trabajo más grandes y complejas.

  • Logra un mejor uso de recursos.

  • Distribuye la fecha de manera más uniforme entre las particiones.

Recomendamos aislar tu colección en las siguientes circunstancias:

  • Si tu partición primaria experimenta una carga de trabajo significativa debido a la presencia de varias colecciones no particionadas de alto rendimiento.

  • Se anticipa que una colección sin particiones experimentará un crecimiento futuro, que podría convertirse en un cuello de botella para otras colecciones.

  • Estás ejecutando un diseño de implementación de una colección por clúster y deseas aislar a esos clientes según la prioridad o cargas de trabajo.

  • Tus particiones tienen más datos de lo proporcional debido a la cantidad de colecciones no fragmentadas ubicadas en ellos.

Para aprender a mover una colección no particionada con mongosh, consulta Mover una colección.

Puedes configurar las funcionalidades de tus implementaciones de MongoDB y de las librerías del driver para crear una aplicación resistente que pueda soportar interrupciones del servicio de red y eventos de failover. Para escribir un código de aplicación que aproveche al máximo las capacidades siempre activas de MongoDB Atlas, debes realizar las siguientes tareas:

Instale las últimas Librerías de clientes para su lenguaje desde Librerías de clientes de MongoDB. Las librerías cliente conectan y transmiten consultas desde tu aplicación a tu base de datos. Utilizar las últimas Librerías de clientes permite acceder a las últimas funcionalidades de MongoDB.

Luego, en tu aplicación, importa la dependencia:

Si usas Maven, añade lo siguiente a tu lista de dependencias pom.xml:

<dependencies>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-sync</artifactId>
<version>4.0.1</version>
</dependency>
</dependencies>

Si está utilizando Gradle, añada lo siguiente a su lista de dependencias build.gradle:

dependencies {
compile 'org.mongodb:mongodb-driver-sync:4.0.1'
}
// Latest 'mongodb' version installed with npm
const MongoClient = require('mongodb').MongoClient;
# Install the latest 'pymongo' version with pip and
# import MongoClient from the package to establish a connection.
from pymongo import MongoClient

Nota

Atlas proporciona una cadena de conexión preconfigurada. Para conocer los pasos para copiarla, consulte Cadenas de conexión proporcionadas por Atlas.

Utiliza una cadena de conexión que especifique todos los nodos en tu clúster de Atlas para conectar tu aplicación a tu base de datos. Si tu clúster realiza una elección de set de réplicas y se elige un nuevo primario, una cadena de conexión que especifica todos los nodos de su clúster detecta el nuevo primario sin lógica de la aplicación.

Puedes especificar todos los nodos de tu clúster usando cualquiera de las siguientes opciones:

La cadena de conexión también puede especificar opciones, especialmente retryWrites y writeConcern.

Atlas puede generar una cadena de conexión SRV optimizada para clústeres particionados utilizando los balanceadores de carga del servicio de nodos privados. Cuando se usa una cadena de conexión optimizada, Atlas limita el número de conexiones por mongos entre la aplicación y el clúster particionado. Las conexiones limitadas por mongos mejoran el rendimiento durante los picos en el número de conexiones.

Para obtener más información sobre las cadenas de conexión optimizadas para clústeres fragmentados detrás de un nodo privado, consulta ¿Cómo puedo optimizar el rendimiento de la conexión para clústeres fragmentados con nodos privados?

Si copias tu cadena de conexión desde la interfaz de tu clúster de Atlas, la cadena de conexión está preconfigurada para tu clúster, utiliza el formato de lista de semillas DNS y la inclusión de las opciones recomendadas de retryWrites y w (nivel de confirmación de escritura (write concern)) para obtener resiliencia.

Para copiar tu URI de la cadena de conexión de Atlas:

1
  1. Si aún no se muestra, seleccione la organización que contiene su proyecto deseado en el menú Organizations de la barra de navegación.

  2. Si aún no aparece, selecciona el proyecto deseado en el menú Projects de la barra de navegación.

  3. En la barra lateral, haz clic en Clusters en la sección Database.

La página de clústeres se muestra.

2
  1. Haz clic en Connect en el clúster al que desees conectar tu aplicación.

  2. Selecciona Drivers como tu método de conexión.

  3. Seleccione su Driver y Version.

3

Copia la cadena de conexión o el ejemplo completo del controlador en el código de tu aplicación. Debes proporcionar credenciales de usuario de base de datos.

Nota

Esta guía utiliza autenticación SCRAM a través de una cadena de conexión. Para aprender sobre el uso de los certificados X.509 para autenticarse, consulta X.509.

Utiliza tu cadena de conexión para crear un cliente de MongoDB en la aplicación:

// Copy the connection string provided by Atlas
String uri = <your Atlas connection string>;
// Instantiate the MongoDB client with the URI
MongoClient client = MongoClients.create(uri);
// Copy the connection string provided by Atlas
const uri = <your Atlas connection string>;
// Instantiate the MongoDB client with the URI
const client = new MongoClient(uri);
# Copy the connection string provided by Atlas
uri = <your Atlas connection string>
# Pass your connection string URI to the MongoClient constructor
client = MongoClient(uri)

Nota

MongoDB vuelve a intentar tanto los guardados como las lecturas una vez por defecto.

Utiliza escrituras reintentables para reintentar ciertas operaciones de escritura una sola vez si fallan. Si copiaste tu cadena de conexión desde Atlas, incluye "retryWrites=true". Si proporcionas tu propia cadena de conexión, incluye "retryWrites=true" como un parámetro de consulta.

Reintentar grabaciones exactamente una vez es la mejor estrategia para manejar errores de red transitorios y elecciones de sets de réplicas en las que la aplicación temporalmente no puede encontrar un nodo primario sano. Si el reintento tiene éxito, la operación en su totalidad tiene éxito y no se devuelve ningún error. Si la operación falla, es probable que sea debido a:

  • Un error de red persistente

  • Un comando inválido

Cuando una operación falla, su aplicación debe gestionar el error por sí misma.

Las operaciones de lectura se reintentan automáticamente una sola vez si fallan. No se requiere configuración adicional para reintentar las lecturas.

Puedes ajustar la coherencia y la disponibilidad de tu aplicación utilizando niveles de confirmación de escritura (write concern) y niveles de consistencia de lectura. Preocupaciones más estrictas implican que las operaciones de la base de datos esperen garantías de coherencia de datos más fuertes, mientras que el alivio de los requisitos de coherencia proporciona una mayor disponibilidad.

Ejemplo

Si su aplicación gestiona saldos monetarios, la coherencia es sumamente importante. Puedes usar las preocupaciones de escritura y el nivel de consistencia de lectura de majority para asegurarte de nunca leer datos obsoletos o datos que puedan ser revertidos.

Alternativamente, si tu aplicación registra datos de temperatura de cientos de sensores cada segundo, es posible que no te preocupe si lees datos que no incluyen las lecturas más recientes. Puedes relajar los requisitos de coherencia y proporcionar acceso más rápido a esos datos.

Puede configurar el nivel de confirmación de escritura (write concern) de su set de réplicas de Atlas a través del URI de cadena de conexión. Usa un majority nivel de confirmación de escritura (write concern) para garantizar que tus datos se escriban correctamente en tu base de datos y se conserven. Esta es la opción por defecto recomendada y suficiente para la mayoría de los casos de uso. Si copiaste tu cadena de conexión de Atlas, incluye "w=majority".

Cuando use un nivel de confirmación de escritura (write concern) que requiera confirmación, como majority, también puede especificar un límite máximo de tiempo para que las escrituras alcancen ese nivel de confirmación:

  • El parámetro de la cadena de conexión wtimeoutMS para todas las escrituras, o

  • La opción wtimeout para una única operación de guardar.

El que utilices o no un límite de tiempo y el valor que utilices depende del contexto de tu aplicación.

Importante

Si no especificas un límite de tiempo para las escrituras y el nivel de confirmación de escritura (write concern) es inalcanzable, la operación de escritura se mantendrá en espera indefinidamente.

Se puede configurar el nivel de consistencia de lectura del set de réplicas de Atlas a través de la URI de cadena de conexión. La nivel de consistencia de lectura ideal depende de los requisitos de tu aplicación, pero el valor por defecto es suficiente para la mayoría de los casos de uso. No se requiere ningún parámetro de cadena de conexión para usar los niveles de consistencia de lectura por defecto.

Especificar un nivel de consistencia de lectura puede mejorar las garantías en torno a los datos que su aplicación recibe de Atlas.

Nota

La combinación específica de write concern y nivel de consistencia de lectura que utiliza tu aplicación afecta las garantías de orden de las operaciones. Esto se denomina coherencia causal. Para obtener más información sobre las garantías de la coherencia causal, consulta Coherencia causal y nivel de confirmación de escritura (write concern).

Los comandos no válidos, las interrupciones de red y los errores de red que no se gestionan mediante escrituras reintentables generan errores. Consulte la documentación de la API de su controlador para obtener más información sobre los errores.

Por ejemplo, si una aplicación intenta insertar un documento que contiene un valor _id que ya se utiliza en la colección de la base de datos, tu driver devuelve un error que incluye:

Unable to insert due to an error: com.mongodb.MongoWriteException:
E11000 duplicate key error collection: <db>.<collection> ...
{
"name": : "MongoError",
"message": "E11000 duplicate key error collection on: <db>.<collection> ... ",
...
}
pymongo.errors.DuplicateKeyError: E11000 duplicate key error collection: <db>.<collection> ...

Sin una gestión adecuada de errores, un error podría evitar que tu aplicación realice el procesamiento de solicitudes hasta que se reinicie.

Tu aplicación debe gestionar errores sin fallos ni efectos secundarios. En el ejemplo anterior de una aplicación que inserta un _id duplicado en una colección, esa aplicación podría gestionar los errores de la siguiente manera:

// Declare a logger instance from java.util.logging.Logger
private static final Logger LOGGER = ...
...
try {
InsertOneResult result = collection.insertOne(new Document()
.append("_id", 1)
.append("body", "I'm a goofball trying to insert a duplicate _id"));
// Everything is OK
LOGGER.info("Inserted document id: " + result.getInsertedId());
// Refer to the API documentation for specific exceptions to catch
} catch (MongoException me) {
// Report the error
LOGGER.severe("Failed due to an error: " + me);
}
...
collection.insertOne({
_id: 1,
body: "I'm a goofball trying to insert a duplicate _id"
})
.then(result => {
response.sendStatus(200) // send "OK" message to the client
},
err => {
response.sendStatus(400); // send "Bad Request" message to the client
});
...
try:
collection.insert_one({
"_id": 1,
"body": "I'm a goofball trying to insert a duplicate _id"
})
return {"message": "User successfully added!"}
except pymongo.errors.DuplicateKeyError as e:
print ("The insert operation failed:", e)

La operación de inserción en este ejemplo arroja un error de "clave duplicada" la segunda vez que se invoca porque el campo _id debe ser único. Se detecta el error, se notifica al cliente y la aplicación sigue funcionando. Sin embargo, la operación de inserción falla y depende de ti decidir si mostrar un mensaje al usuario, reintentar la operación o hacer otra cosa.

Siempre se deben registrar los errores. Las estrategias comunes para el procesamiento adicional de errores incluyen:

  • Devuelva el error al cliente con un mensaje de error. Esta es una buena estrategia cuando no puedes resolver el error y necesitas informar a un usuario de que no se puede completar una acción.

  • Escribe en una base de datos de copias de seguridad. Esta es una buena estrategia cuando no puedes resolver el error pero no quieres arriesgarte a perder los datos de la solicitud.

  • Reintente la operación más allá del único reintento predeterminado. Esta es una buena estrategia cuando puede resolver la causa de un error mediante programación y luego reintentarla.

Debe seleccionar las mejores estrategias para el contexto de su aplicación.

Ejemplo

En el ejemplo de un error de clave duplicada, debe registrar el error pero no volver a intentar la operación porque nunca tendrá éxito. En su lugar, puedes guardar en una base de datos alternativa y revisar el contenido de esa base de datos en un momento posterior para garantizar que no se pierda ninguna información. El usuario no necesita hacer nada más y los datos están registrados, por lo que puedes optar por no enviar un mensaje de error al cliente.

Devolver un error puede ser un comportamiento deseable cuando una operación pueda quedar colgada indefinidamente e impedir que tu aplicación ejecute nuevas operaciones. Puedes usar el método maxTimeMS para establecer un límite de tiempo en operaciones individuales, devolviendo un error para que tu aplicación lo gestione si se excede ese límite de tiempo.

El límite de tiempo que se establezca para cada operación depende del contexto de esa operación.

Ejemplo

Si tu aplicación lee y muestra información de producto sencilla desde una colección inventory, puedes tener la confianza razonable de que esas operaciones de lectura solo toman un momento. Una query que se ejecuta inusualmente durante mucho tiempo es un buen indicador de que hay un problema de red persistente. Configurar maxTimeMS en esa operación a 5000, o 5 segundos, significa que tu aplicación recibe retroalimentación tan pronto como estés seguro de que hay un problema de red.

En el espíritu de pruebas de caos, Atlas realizará elecciones de set de réplicas automáticamente para tareas de mantenimiento periódicas y ciertos cambios de configuración.

Para comprobar si tu aplicación es resiliente a las elecciones del set de réplicas, prueba el proceso de failover simulando un evento de failover.

La aplicación de ejemplo reúne las siguientes recomendaciones para garantizar la resiliencia frente a interrupciones del servicio de red y eventos de conmutación por error:

  • Utilice la cadena de conexión proporcionada por Atlas con escrituras reintentables, nivel de confirmación de escritura de mayoría y nivel de consistencia de lectura por defecto.

  • Especificar un límite de operation time con el método maxTimeMS. Para obtener instrucciones sobre cómo configurar maxTimeMS, consulta tu documentación del driver.

  • Gestione errores por claves duplicadas y "timeouts".

La aplicación es una API HTTP que permite a los clientes crear o listar registros de usuarios. Expone un endpoint que acepta solicitudes GET y POST http://localhost:3000:

Método
Endpoint
Descripción

GET

/users

Obtiene una lista de nombres de usuario de una colección users.

POST

/users

Requiere un name en el cuerpo de la solicitud. Agrega un nuevo usuario a una colección users.

Nota

La siguiente aplicación de servidor utiliza NanoHTTPD y json que debes añadir a tu proyecto como dependencias antes de poder ejecutarla.

1// File: App.java
2
3import java.util.Map;
4import java.util.logging.Logger;
5
6import org.bson.Document;
7import org.json.JSONArray;
8
9import com.mongodb.MongoException;
10import com.mongodb.client.MongoClient;
11import com.mongodb.client.MongoClients;
12import com.mongodb.client.MongoCollection;
13import com.mongodb.client.MongoDatabase;
14
15import fi.iki.elonen.NanoHTTPD;
16
17public class App extends NanoHTTPD {
18 private static final Logger LOGGER = Logger.getLogger(App.class.getName());
19
20 static int port = 3000;
21 static MongoClient client = null;
22
23 public App() throws Exception {
24 super(port);
25
26 // Replace the uri string with your MongoDB deployment's connection string
27 String uri = "<atlas-connection-string>";
28 client = MongoClients.create(uri);
29
30 start(NanoHTTPD.SOCKET_READ_TIMEOUT, false);
31 LOGGER.info("\nStarted the server: http://localhost:" + port + "/ \n");
32 }
33
34 public static void main(String[] args) {
35 try {
36 new App();
37 } catch (Exception e) {
38 LOGGER.severe("Couldn't start server:\n" + e);
39 }
40 }
41
42 @Override
43 public Response serve(IHTTPSession session) {
44 StringBuilder msg = new StringBuilder();
45 Map<String, String> params = session.getParms();
46
47 Method reqMethod = session.getMethod();
48 String uri = session.getUri();
49
50 if (Method.GET == reqMethod) {
51 if (uri.equals("/")) {
52 msg.append("Welcome to my API!");
53 } else if (uri.equals("/users")) {
54 msg.append(listUsers(client));
55 } else {
56 msg.append("Unrecognized URI: ").append(uri);
57 }
58 } else if (Method.POST == reqMethod) {
59 try {
60 String name = params.get("name");
61 if (name == null) {
62 throw new Exception("Unable to process POST request: 'name' parameter required");
63 } else {
64 insertUser(client, name);
65 msg.append("User successfully added!");
66 }
67 } catch (Exception e) {
68 msg.append(e);
69 }
70 }
71
72 return newFixedLengthResponse(msg.toString());
73 }
74
75 static String listUsers(MongoClient client) {
76 MongoDatabase database = client.getDatabase("test");
77 MongoCollection<Document> collection = database.getCollection("users");
78
79 final JSONArray jsonResults = new JSONArray();
80 collection.find().forEach((result) -> jsonResults.put(result.toJson()));
81
82 return jsonResults.toString();
83 }
84
85 static String insertUser(MongoClient client, String name) throws MongoException {
86 MongoDatabase database = client.getDatabase("test");
87 MongoCollection<Document> collection = database.getCollection("users");
88
89 collection.insertOne(new Document().append("name", name));
90 return "Successfully inserted user: " + name;
91 }
92}

Nota

La siguiente aplicación de servidor utiliza Express, que debes agregar como una dependencia a tu proyecto antes de poder ejecutarlo.

1const express = require('express');
2const bodyParser = require('body-parser');
3
4// Use the latest client libraries by installing & importing them
5const MongoClient = require('mongodb').MongoClient;
6
7const app = express();
8app.use(bodyParser.json());
9app.use(bodyParser.urlencoded({ extended: true }));
10
11const uri = "mongodb+srv://<db_username>:<db_password>@cluster0-111xx.mongodb.net/test?retryWrites=true&w=majority";
12
13const client = new MongoClient(uri);
14
15// ----- API routes ----- //
16app.get('/', (req, res) => res.send('Welcome to my API!'));
17
18app.get('/users', (req, res) => {
19 const collection = client.db("test").collection("users");
20
21 collection
22 .find({})
23 .maxTimeMS(5000)
24 .toArray((err, data) => {
25 if (err) {
26 res.send("The request has timed out. Please check your connection and try again.");
27 }
28 return res.json(data);
29 });
30});
31
32app.post('/users', (req, res) => {
33 const collection = client.db("test").collection("users");
34 collection.insertOne({ name: req.body.name })
35 .then(result => {
36 res.send("User successfully added!");
37 }, err => {
38 res.send("An application error has occurred. Please try again.");
39 })
40});
41// ----- End of API routes ----- //
42
43app.listen(3000, () => {
44 console.log(`Listening on port 3000.`);
45 client.connect(err => {
46 if (err) {
47 console.log("Not connected: ", err);
48 process.exit(0);
49 }
50 console.log('Connected.');
51 });
52});

Nota

La siguiente aplicación web utiliza FastAPI. Para crear una nueva aplicación, se debe usar la estructura del archivo de muestra de FastAPI.

1# File: main.py
2
3from fastapi import FastAPI, Body, Request, Response, HTTPException, status
4from fastapi.encoders import jsonable_encoder
5
6from typing import List
7from models import User
8
9import pymongo
10from pymongo import MongoClient
11from pymongo import errors
12
13# Replace the uri string with your |service| connection string
14uri = "<atlas-connection-string>"
15db = "test"
16
17app = FastAPI()
18
19@app.on_event("startup")
20def startup_db_client():
21 app.mongodb_client = MongoClient(uri)
22 app.database = app.mongodb_client[db]
23
24@app.on_event("shutdown")
25def shutdown_db_client():
26 app.mongodb_client.close()
27
28##### API ROUTES #####
29@app.get("/users", response_description="List all users", response_model=List[User])
30def list_users(request: Request):
31 try:
32 users = list(request.app.database["users"].find().max_time_ms(5000))
33 return users
34 except pymongo.errors.ExecutionTimeout:
35 raise HTTPException(status_code=status.HTTP_503_SERVICE_UNAVAILABLE, detail="The request has timed out. Please check your connection and try again.")
36
37@app.post("/users", response_description="Create a new user", status_code=status.HTTP_201_CREATED)
38def new_user(request: Request, user: User = Body(...)):
39 user = jsonable_encoder(user)
40 try:
41 new_user = request.app.database["users"].insert_one(user)
42 return {"message":"User successfully added!"}
43 except pymongo.errors.DuplicateKeyError:
44 raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Could not create user due to existing '_id' value in the collection. Try again with a different '_id' value.")