Ir al contenido principal

MongoDB y GraphQL: una combinación perfecta

Aprende a crear una API GraphQL con TypeScript y MongoDB, una combinación no solo eficiente, sino además muy fácil de usar.
Actualizado 17 sept 2026  · 11 min leer

Explorar con IA

ChatGPTClaudePerplexity

GraphQL es una forma potente y eficiente de crear APIs. El cliente consulta la API, de forma parecida a como lo haría con una base de datos, y esa API devuelve solo los datos solicitados, lo que suele reducir el tamaño de la respuesta y mejorar los tiempos de carga. En el mundo actual, los tiempos de respuesta bajos son clave.

Cuando combinas una API GraphQL con MongoDB, no solo obtienes respuestas rápidas: también trabajas con un formato de datos coherente de principio a fin.

Imagina esto: tu cliente ejecuta una consulta GraphQL con una estructura similar a JSON. Cuando los datos llegan a tu aplicación —pongamos TypeScript en este ejemplo— sigues trabajando con un formato parecido a JSON. Y si damos un paso más, al usar MongoDB, los datos que envías y recibes también se parecen a JSON. En resumen, obtienes una experiencia de datos coherente con gran rendimiento. No tendrás que preocuparte tanto de manipular y dar formato a los datos; podrás centrarte en la experiencia de usuario de tu aplicación y no en la base de datos ni en las herramientas.

En este tutorial verás lo sencillo que es usar MongoDB en tu API GraphQL, esta vez con TypeScript.

Requisitos previos

Para este tutorial, asegúrate de tener listo lo siguiente antes de empezar:

  • Un clúster de MongoDB Atlas
  • Node.js 22+
  • MongoDB Node.js Driver 6.x

En este tutorial no haremos nada especialmente complejo a nivel de base de datos, así que sirve cualquier nivel de clúster de MongoDB, incluso el gratuito. No obstante, aquí no veremos cómo aprovisionar un clúster de MongoDB Atlas. Se da por hecho que ya tienes configuradas las reglas de usuario y de red. Si necesitas ayuda para empezar, consulta la documentación de introducción a Atlas.

Necesitarás crear una aplicación Node.js. Si quieres, puedes ejecutar los siguientes comandos:

mkdir graphql_example
cd graphql_example
npm init -y

Estos comandos crean un directorio de proyecto y un package.json básico. Usaremos TypeScript, Express Framework, MongoDB y Apollo en este proyecto. Instálalos con estos comandos:

npm install @apollo/server@4 body-parser cors dotenv express@4 graphql mongodb
npm install @types/cors @types/express@4 @types/node tsx typescript --save-dev

Estos comandos instalarán las dependencias y también las definiciones de tipos para usarlas en TypeScript.

Como último requisito, necesitas un archivo de configuración para TypeScript. En la raíz del proyecto, crea un tsconfig.json con el siguiente JSON:

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "commonjs",
    "lib": ["ES2020"],
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "resolveJsonModule": true,
    "moduleResolution": "node",
    "declaration": true,
    "declarationMap": true,
    "sourceMap": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist"]
}

Si en algún momento quieres ver el proyecto completo o probarlo, puedes echarle un vistazo en GitHub.

Crea la base con Apollo, Express y las dependencias de MongoDB

A nivel de estructura del proyecto, usaremos lo siguiente:

  • src/database/connection.ts
  • src/database/userService.ts
  • src/resolvers/index.ts
  • src/schema/typeDefs.ts
  • src/types/index.ts
  • src/index.ts
  • .env

El archivo src/index.ts contendrá todo el arranque de Express Framework y Apollo. Es decir, el inicio del servidor, la definición del endpoint GraphQL, etc. En src/types/index.ts estarán las definiciones TypeScript para trabajar con el modelo de datos de la base de datos dentro de la aplicación. No lo confundas con src/schema/typeDefs.ts que, aunque similar, se centra en las definiciones de tipos de GraphQL.

Esto nos deja con los directorios database y resolvers. La mayor parte de la lógica de aplicación y base de datos estará ahí; lo veremos enseguida.

Por ahora, centrémonos en configurar el servidor en src/index.ts:

import 'dotenv/config';
import { ApolloServer } from '@apollo/server';
import { expressMiddleware } from '@apollo/server/express4';
import express from 'express';
import http from 'http';
import cors from 'cors';
import bodyParser from 'body-parser';
import { typeDefs } from './schema/typeDefs';
import { resolvers } from './resolvers';

async function startServer() {
  try {

    const app = express();
    
    const httpServer = http.createServer(app);

    const server = new ApolloServer({
      typeDefs,
      resolvers,
    });

    await server.start();

    app.use(
      '/graphql',
      cors<cors.CorsRequest>(),
      bodyParser.json(),
      expressMiddleware(server)
    );

    const PORT = process.env.PORT || 3000;
    await new Promise<void>((resolve) => httpServer.listen({ port: PORT }, resolve));
    
    console.log(Server ready at http://localhost:${PORT}/graphql);

  } catch (error) {
    console.error('Error starting server:', error);
    process.exit(1);
  }
}

startServer();

Iremos ampliando este archivo según avancemos.

Para empezar, importamos todas las dependencias del proyecto. Después, configuramos el servidor de Express y el middleware de Apollo.

const server = new ApolloServer({
  typeDefs,
  resolvers,
});

Aún no hemos añadido nada a src/schema/typeDefs.ts ni a src/resolvers/index.ts, pero en esta fase lo estamos dejando todo listo. No podrás ejecutar el servidor sin errores hasta que completemos lo que falta en el resto de archivos.

Conviene mencionar que este ejemplo permite peticiones desde todos los orígenes por lo siguiente:

cors<cors.CorsRequest>(),

Esto está bien en desarrollo, pero en producción limita los orígenes solo a los que necesites.

Interactuar con MongoDB desde la aplicación TypeScript con Node.js

Aunque ya tenemos la base de Express y Apollo, aún no hemos configurado MongoDB en la aplicación. Antes de meternos en el código, añade la información de conexión al archivo .env:

MONGODB_URI="mongodb+srv://<USERNAME>:<PASSWORD>@<HOST>/?appName=devrel-graphql"
DB_NAME="graphql_example"

Sustituye <USERNAME>, <PASSWORD> y <HOST> con los datos de tu clúster de MongoDB Atlas, que encontrarás en tu panel de MongoDB Atlas.

Ahora, vamos a establecer la lógica de conexión a la base de datos. En el archivo **src/database/connection.ts**, añade lo siguiente:

import { MongoClient, Db } from 'mongodb';

let db: Db | null = null;
let client: MongoClient | null = null;

export async function connectToDatabase(): Promise<Db> {
  if (db) {
    return db;
  }

  try {
    const MONGODB_URI = process.env.MONGODB_URI;
    if (!MONGODB_URI) {
      throw new Error('MONGODB_URI is not set');
    }
    const DB_NAME = process.env.DB_NAME || 'graphql_example';
    const APP_NAME = process.env.APP_NAME || 'devrel-graphql';

    console.log('Connecting to MongoDB...');
    
    client = new MongoClient(MONGODB_URI, { appName: APP_NAME });
    await client.connect();
    
    db = client.db(DB_NAME);
    
    console.log(Successfully connected to MongoDB database: ${DB_NAME});
    
    return db;
  } catch (error) {
    console.error('MongoDB connection error:', error);
    throw error;
  }
}

export function getDatabase(): Db {
  if (!db) {
    throw new Error('Database not initialized. Call connectToDatabase() first.');
  }
  return db;
}

export async function closeDatabase(): Promise<void> {
  if (client) {
    await client.close();
    db = null;
    client = null;
    console.log('MongoDB connection closed');
  }
}

La idea aquí es crear una conexión singleton. Hay muchas otras formas de integrar MongoDB en tu aplicación, pero esta es la ruta que elegimos para este ejemplo.

La función connectToDatabase toma la información de conexión del archivo **.env**, se conecta y devuelve la base de datos definida. Si falla, captura y relanza el error. Solo deberías usar connectToDatabase al arrancar el servidor, como viste en el archivo anterior.

La función getDatabase se usará cada vez que llegue una petición a nuestra aplicación. Así obtenemos la instancia actual de la conexión.

Y por último, para dejarlo todo limpio, tenemos closeDatabase para cerrar la conexión cuando el servidor se detiene. Depende de ti si quieres incluirla, pero es una buena práctica.

Antes de entrar en la lógica de base de datos, es buena idea definir los tipos de TypeScript para nuestros DTO (data transfer objects):

export interface User {
  id: string;
  name: string;
  email: string;
  age?: number;
  createdAt: string;
}

export interface CreateUserInput {
  name: string;
  email: string;
  age?: number;
}

export interface UpdateUserInput {
  id: string;
  name?: string;
  email?: string;
  age?: number;
}

Estas interfaces, en **src/types/index.ts**, las gestiona nuestra API, pero la lógica de base de datos también debe conocerlas. Lo verás enseguida.

Pasamos ya a las operaciones reales con la base de datos: crear, leer, actualizar y borrar (CRUD). Esto lo haremos en src/database/userService.ts. La idea es que los resolvers de GraphQL gestionen la lógica de aplicación y llamen a las funciones de este servicio, y el servicio gestione la lógica de base de datos.

En src/database/userService.ts tenemos el siguiente código:

import { Collection, ObjectId } from 'mongodb';
import { getDatabase } from './connection';
import { User, CreateUserInput, UpdateUserInput } from '../types';

interface UserDocument {
  _id: ObjectId;
  name: string;
  email: string;
  age?: number;
  createdAt: Date;
}

export class UserService {
  private collection: Collection<UserDocument>;

  constructor() {
    const db = getDatabase();
    this.collection = db.collection<UserDocument>('users');
  }

  private toUser(doc: UserDocument): User {
    return {
      id: doc._id.toString(),
      name: doc.name,
      email: doc.email,
      age: doc.age,
      createdAt: doc.createdAt.toISOString(),
    };
  }

  async getAllUsers(): Promise<User[]> {
    const users = await this.collection.find().toArray();
    return users.map(doc => this.toUser(doc));
  }

  async getUserById(id: string): Promise<User | null> {
    try {
      const doc = await this.collection.findOne({ _id: new ObjectId(id) });
      return doc ? this.toUser(doc) : null;
    } catch (error) {
      return null;
    }
  }

  async createUser(input: CreateUserInput): Promise<User> {
    const newUser: Omit<UserDocument, '_id'> = {
      name: input.name,
      email: input.email,
      age: input.age,
      createdAt: new Date(),
    };

    const result = await this.collection.insertOne(newUser as UserDocument);
    
    const createdUser = await this.collection.findOne({ _id: result.insertedId });
    
    if (!createdUser) {
      throw new Error('Failed to create user');
    }

    return this.toUser(createdUser);
  }

  async updateUser(input: UpdateUserInput): Promise<User | null> {
    try {
      const updateFields: Partial<Omit<UserDocument, '_id'>> = {};
      
      if (input.name !== undefined) updateFields.name = input.name;
      if (input.email !== undefined) updateFields.email = input.email;
      if (input.age !== undefined) updateFields.age = input.age;

      const result = await this.collection.findOneAndUpdate(
        { _id: new ObjectId(input.id) },
        { $set: updateFields },
        { returnDocument: 'after' }
      );

      return result ? this.toUser(result) : null;
    } catch (error) {
      return null;
    }
  }

  async deleteUser(id: string): Promise<boolean> {
    try {
      const result = await this.collection.deleteOne({ _id: new ObjectId(id) });
      return result.deletedCount > 0;
    } catch (error) {
      return false;
    }
  }

  async createIndexes(): Promise<void> {
    await this.collection.createIndex({ email: 1 }, { unique: true });
    await this.collection.createIndex({ createdAt: -1 });
    console.log('Database indexes created');
  }
}

Lo primero que verás arriba es esta interfaz:

interface UserDocument {
  _id: ObjectId;
  name: string;
  email: string;
  age?: number;
  createdAt: Date;
}

Se parece a nuestra interfaz User, pero no es exactamente igual. UserDocument refleja con más fidelidad cómo trabaja la base de datos. En la base usamos ObjectId, mientras que en la aplicación usamos cadenas. En MongoDB, el id se representa como _id en lugar de id, como en la interfaz User.

Con esto, pasamos a la clase UserService.

Tras obtener el handler de la colección desde la instancia de base de datos en el constructor, tenemos esta serie de funciones:

  • toUser
  • getAllUsers
  • getUserById
  • createUser
  • updateUser
  • deleteUser
  • createIndexes

La función toUser es básicamente un helper que convierte entre User y UserDocument. En la base de datos enviamos y recibimos UserDocument, y necesitamos convertirlo para manejar User en la aplicación.

async createIndexes(): Promise<void> {
	await this.collection.createIndex({ email: 1 }, { unique: true });
	await this.collection.createIndex({ createdAt: -1 });
	console.log('Database indexes created');
}

La función createIndexes creará algunos índices de ejemplo que pueden ser útiles. Por defecto, solo existe un índice en el campo _id, lo cual vale para una demo con pocos documentos, pero a medida que tu aplicación crezca, no ignores la creación adecuada de índices según tus datos y consultas. Los dos de arriba son solo ejemplos.

Ahora podemos revisar cada función del servicio empezando por getAllUsers:

async getAllUsers(): Promise<User[]> {
	const users = await this.collection.find().toArray();
	return users.map(doc => this.toUser(doc));
}

Esta función devuelve todos los documentos de la colección porque no hay filtro en find. Convertimos los resultados con toUser y los devolvemos a la aplicación, que más adelante serán nuestros resolvers de Apollo.

async getUserById(id: string): Promise<User | null> {
	try {
	  const doc = await this.collection.findOne({ _id: new ObjectId(id) });
	  return doc ? this.toUser(doc) : null;
	} catch (error) {
	  return null;
	}
}

La función getByUserId es similar, pero aquí usamos findOne con un criterio de filtro: queremos un único usuario por su campo único _id. Como en la interfaz User el id es una cadena, lo envolvemos con ObjectId para que sea válido en las consultas a MongoDB.

Pasamos a crear datos en MongoDB con createUser:

async createUser(input: CreateUserInput): Promise<User> {
	const newUser: Omit<UserDocument, '_id'> = {
	  name: input.name,
	  email: input.email,
	  age: input.age,
	  createdAt: new Date(),
	};
	
	const result = await this.collection.insertOne(newUser as UserDocument);
	
	const createdUser = await this.collection.findOne({ _id: result.insertedId });
	
	if (!createdUser) {
	  throw new Error('Failed to create user');
	}
	
	return this.toUser(createdUser);
}

Tras insertar con insertOne, usamos el insertedId devuelto para consultar ese mismo documento. Lo hacemos porque en una API GraphQL, cuando se crea un dato, normalmente se espera poder consultarlo en la misma mutación.

La función updateUser es un poco distinta:

async updateUser(input: UpdateUserInput): Promise<User | null> {
	try {
	  const updateFields: Partial<Omit<UserDocument, '_id'>> = {};
	  
	  if (input.name !== undefined) updateFields.name = input.name;
	  if (input.email !== undefined) updateFields.email = input.email;
	  if (input.age !== undefined) updateFields.age = input.age;
	
	  const result = await this.collection.findOneAndUpdate(
		{ _id: new ObjectId(input.id) },
		{ $set: updateFields },
		{ returnDocument: 'after' }
	  );
	
	  return result ? this.toUser(result) : null;
	} catch (error) {
	  return null;
	}
}

En esta aplicación solo permitimos actualizar los campos name, email y age. Todos son opcionales, así que los añadimos al criterio de actualización solo si están presentes.

Esto nos lleva a findOneAndUpdate.

El primer objeto es el filtro: solo queremos actualizar donde _id coincide. Para cualquier coincidencia usamos el operador $set para reemplazar o crear los campos de updateFields. Los campos que no aparezcan no se tocan. Por último, como buscamos y actualizamos, establecemos returnDocument en after para recibir el documento ya modificado y no el original. Si usáramos updateOne en lugar de findOneAndUpdate, solo obtendríamos información de la operación, no los datos.

La última operación CRUD es borrar datos de MongoDB con deleteUser:

async deleteUser(id: string): Promise<boolean> {
	try {
	  const result = await this.collection.deleteOne({ _id: new ObjectId(id) });
	  return result.deletedCount > 0;
	} catch (error) {
	  return false;
	}
}

La función deleteOne se parece a findOne porque usamos un filtro por _id. La diferencia es que cualquier coincidencia —como máximo un documento— se borrará.

A estas alturas, la lógica de base de datos ya está lista. Para finalizarla, conecta desde **src/index.ts**:

// Previous imports here...
import { connectToDatabase, closeDatabase } from './database/connection';
import { UserService } from './database/userService';

async function startServer() {
  try {

    await connectToDatabase();
    
    const userService = new UserService();
    await userService.createIndexes();
    
    // The rest of the file here...
}

En este fragmento hemos omitido la mayor parte de src/index.ts. El objetivo es mostrar el uso de connectToDatabase y la creación de índices. En resumen, añade esas tres líneas al principio de tu función startServer.

A partir de aquí, podemos centrarnos en la lógica de la API.

Define los tipos de GraphQL, los resolvers y la lógica de aplicación

Ya tenemos definidos los tipos de TypeScript para trabajar con la base y para mover datos por la aplicación. Pero aún no hemos creado las definiciones de tipos de GraphQL, que determinan con qué puede interactuar el usuario al usar nuestra API.

En src/schema/typeDefs.ts, añade lo siguiente:

export const typeDefs = #graphql
  type User {
    id: ID!
    name: String!
    email: String!
    age: Int
    createdAt: String!
  }

  type Query {
    users: [User!]!
    user(id: ID!): User
  }

  type Mutation {
    createUser(name: String!, email: String!, age: Int): User!
    updateUser(id: ID!, name: String, email: String, age: Int): User
    deleteUser(id: ID!): Boolean!
  }
;

El tipo User define qué puede solicitar el cliente en una consulta. En este ejemplo coincide con la interfaz User, pero no tiene por qué. Por ejemplo, quizá tu interfaz User incluye datos que nunca querrás devolver al cliente, como una contraseña.

El tipo Query define qué consultas se pueden ejecutar en la API. Cada consulta devuelve un User o un array de User, pero podemos añadir lógica específica en medio.

El tipo Mutation es similar a Query, pero pensado para operaciones que modifican datos.

Con las definiciones de tipos listas, podemos centrarnos en la lógica de los resolvers. En src/resolvers/index.ts, incluye lo siguiente:

import { UserService } from '../database/userService';
import { User, CreateUserInput, UpdateUserInput } from '../types';

export const resolvers = {
  Query: {
    users: async (): Promise<User[]> => {
      const userService = new UserService();
      return await userService.getAllUsers();
    },

    user: async (_: unknown, { id }: { id: string }): Promise<User | null> => {
      const userService = new UserService();
      return await userService.getUserById(id);
    },
  },

  Mutation: {
    createUser: async (
      _: unknown,
      { name, email, age }: CreateUserInput
    ): Promise<User> => {
      const userService = new UserService();
      return await userService.createUser({ name, email, age });
    },

    updateUser: async (
      _: unknown,
      { id, name, email, age }: UpdateUserInput
    ): Promise<User | null> => {
      const userService = new UserService();
      return await userService.updateUser({ id, name, email, age });
    },

    deleteUser: async (_: unknown, { id }: { id: string }): Promise<boolean> => {
      const userService = new UserService();
      return await userService.deleteUser(id);
    },
  },
};

Estos resolvers son la extensión natural de lo que vimos en el archivo de definiciones de tipos para consultas y mutaciones.

Fíjate en la consulta users:

users: async (): Promise<User[]> => {
  const userService = new UserService();
  return await userService.getAllUsers();
},

Esta consulta GraphQL usa nuestro UserService, parte de la lógica de base de datos, para obtener todos los usuarios. El User[] resultante se devuelve al cliente, pero solo con los campos que haya pedido y que estén definidos en los tipos GraphQL.

Por ejemplo, si el cliente envía esta consulta:

query {
	users {
		name
		email
	}
}

En este ejemplo tenemos más campos disponibles, pero el cliente solo quiere name y email. Esto se gestiona en base a nuestras definiciones de tipos GraphQL. Apollo se encarga de la magia.

Estas mismas reglas aplican a cada consulta y mutación en **src/resolvers/index.ts**.

createUser: async (
  _: unknown,
  { name, email, age }: CreateUserInput
): Promise<User> => {
  const userService = new UserService();
  return await userService.createUser({ name, email, age });
},

En la definición de createUser vimos que el cliente puede pasar name, email y age. En el resolver hacemos lo mismo y llamamos a createUser en nuestro servicio de base de datos. La respuesta se devuelve al cliente con los campos que haya solicitado.

Compila y ejecuta la API GraphQL

Llegados a este punto, la API GraphQL debería estar en muy buen estado. Hay varias formas de compilar y ejecutar la aplicación.

Por ejemplo, puedes añadir lo siguiente a tu **package.json**:

"scripts": {
	"build": "tsc",
	"start": "node dist/index.js",
	"dev": "tsx src/index.ts",
	"dev:watch": "tsx watch src/index.ts",
	"watch": "tsc -w"
},

Si optas por esta vía, ejecuta npm run build para compilar el proyecto y npm run start para servirlo. El puerto por defecto es el 3000, y puedes probarlo con cURL o la herramienta que prefieras.

Conclusión

Has visto cómo crear una API GraphQL con TypeScript y MongoDB como base de datos. Aunque el ejemplo es sencillo, hemos construido consultas y mutaciones para realizar operaciones CRUD contra la base. MongoDB encaja a la perfección en una API GraphQL porque el formato de los datos es similar de principio a fin. Por ejemplo, el cliente envía una consulta con apariencia de JSON. Los datos que viajan por la consulta pueden usarse con un formateo mínimo, y lo mismo al enviarlos a la base y recibirlos de ella. La experiencia es fluida y te permite centrarte en la experiencia de usuario y no en manipular datos para ajustarlos a la base.

Si te has atascado en algún punto, no dudes en revisar el proyecto final en GitHub.

FAQs

¿Por qué debería usar GraphQL?

GraphQL mola porque puedes consultar una API como si fuera una base de datos y pedir solo lo que necesitas. Eso hace que el cliente sea más ligero y eficiente.

¿Es Apollo la única opción para GraphQL?

Apollo facilita mucho crear APIs GraphQL, aunque no es la única opción. Sin embargo, el resto de alternativas se salen del alcance de este tutorial.

¿Por qué usar MongoDB con GraphQL?

Ambos trabajan con formatos de datos similares a JSON, así que no tienes que estar convirtiendo estructuras a cada paso desde la base de datos hasta la API y el cliente.

¿Qué hace un resolver?

Un resolver es una función que le indica a GraphQL cómo obtener o modificar los datos de un campo concreto de tu esquema.

¿Cuál es la diferencia entre una query y una mutación?

Las queries sirven para leer/recuperar datos (como las peticiones GET), mientras que las mutaciones son para crear, actualizar o borrar datos (como POST, PUT, DELETE).


Nic Raboy's photo
Author
Nic Raboy

Nic Raboy es Jefe de Relaciones con Desarrolladores en MongoDB, donde dirige un equipo de programadores de Python, Java, C# y PHP que crean contenido impresionante para ayudar a los programadores a incluir con éxito MongoDB en sus proyectos. Tiene experiencia con Golang y JavaScript y escribe a menudo sobre muchas de sus aventuras de desarrollo.

Temas
MongoDB

Los mejores cursos de DataCamp

Curso

Introducción a MongoDB en Python

3 h
24.3K
Aprende a manipular y analizar datos estructurados de forma flexible con MongoDB.
Ver detallesRight Arrow
Iniciar Curso
Ver másRight Arrow
Relacionado

blog

Contratos de datos desmitificados: Todo lo que necesitas saber

Lograr la escalabilidad en los sistemas de datos distribuidos y reducir los errores.
Mike Shakhomirov's photo

Mike Shakhomirov

11 min

Tutorial

Guía de modelado de datos de MongoDB para aplicaciones de blogs

Aprende algunas posibilidades de modelado de datos que incluyen documentos anidados al diseñar un sistema de gestión de contenidos (CMS) o una aplicación de blog.
Nic Raboy's photo

Nic Raboy

Tutorial

Base de datos Azure SQL: Configuración y gestión paso a paso

Aprende a crear, conectar, gestionar, consultar y proteger tu base de datos Azure SQL. Esta guía paso a paso cubre todo lo esencial para una configuración óptima de la base de datos.
Anneleen Rummens's photo

Anneleen Rummens

12 min

Tutorial

Tutorial de FastAPI: Introducción al uso de FastAPI

Explore el marco FastAPI y descubra cómo puede utilizarlo para crear API en Python.
Moez Ali's photo

Moez Ali

13 min

Tutorial

Desarrollo backend con Python: guía completa para principiantes

Esta guía completa te enseña los fundamentos del backend con Python. Aprende conceptos básicos, frameworks y buenas prácticas para empezar a crear aplicaciones web.
Oluseye Jeremiah's photo

Oluseye Jeremiah

15 min

Tutorial

Python JSON Data: Una guía con ejemplos

Aprende a trabajar con JSON en Python, incluyendo serialización, deserialización, formateo, optimización del rendimiento, manejo de API y comprensión de las limitaciones y alternativas de JSON.
Moez Ali's photo

Moez Ali

6 min

Ver MásVer Más