Cree su propia API utilizando estas tecnologías web populares.
GraphQL y NestJS forman una excelente asociación, ya que le brindan una base sólida para sus API y un marco fácil de usar para crear aplicaciones web escalables. La combinación es perfecta para crear aplicaciones listas para producción y ambas son herramientas muy relevantes en el ecosistema tecnológico actual.
Obtenga más información sobre cómo puede crear una API con ambos productos.
¿Qué es GraphQL?
GraphQL es un lenguaje de consulta y manipulación de datos puede usar para crear API de una manera más precisa y concisa. GraphQL proporciona una descripción completa y adecuada de los datos existentes en una API y le da poder al cliente para obtener los datos exactos que necesita.
GraphQL proporciona muchas funciones de las que carecen las API REST, que van desde consultas de datos precisas hasta mejores herramientas para desarrolladores, como el gráfico editor. También le permite consultar múltiples recursos a través de una sola solicitud.
¿Qué es NestJS?
NestJS es un marco progresivo de Node.js que puede usar para crear aplicaciones del lado del servidor escalables y eficientes. NestJS proporciona muchos complementos, junto con herramientas para un desarrollo rápido y sencillo, incluida la compatibilidad con GraphQL, GRPC, WebSockets, etc.
NestJS es bien conocido en el ecosistema por su estructura de proyecto optimizada que utiliza módulos, controladores, servicios y esquemas. Su CLI integrada le permite crear una arquitectura de API estructurada. Puedes usar principios de inyección de dependencia para controlar cómo las partes de una aplicación se comunican entre sí.
Implementando GraphQL con NestJS y MongoDB
Antes de crear una API con NestJS y GraphQL, deberá tener disponibles las dependencias adecuadas. Necesitas para instalar Node.js y NestJS, que puede instalar ejecutando npm i -g @nestjs/cli.
El ejemplo que sigue es una aplicación simple que almacena información sobre libros. Ejecute el siguiente comando en su terminal para crear una nueva aplicación NestJS:
nido nuevo
Navegue al directorio de la aplicación generada () e instalar sus dependencias con el siguiente comando:
$ npm install --save @nestjs/config @nestjs/graphql graphql-tools graphql \
@nestjs/apollo apollo-server-express @nestjs/mongoose @types/graphql
Existen dos enfoques principales para crear API de GraphQL, a saber:
- Enfoque de esquema primero: donde describe la API en archivos de definición de esquema o SDL, y NestJS genera definiciones de Typescript basadas en ellos.
- Enfoque de código primero: donde define consultas, mutaciones y otras funcionalidades de GraphQL utilizando clases y decoradores de Typescript, y NestJS genera archivos SDL basados en ellos.
El siguiente ejemplo describe cómo usar un enfoque de código primero.
Primero, necesita inicializar GraphQL en su módulo de aplicación y conectarlo a una base de datos MongoDB:
// aplicación.módulo.ts
importar { Módulo } de'@nestjs/común';
importar { Módulo GraphQL como Módulo NestGraphQL } de'@nestjs/graphql';
importar {ApoloDriver, ApolloDriverConfig} de'@nestjs/apolo';
importar { unirse } de'camino';
importar { Módulo Mongoose } de'@nestjs/mangosta';
importar { Controlador de aplicaciones } de'./aplicación.controlador';
importar { Servicio de aplicaciones } de'./aplicación.servicio';
importar { Módulo de configuración, Servicio de configuración } de'@nestjs/config';
importar mongodbConfig de'./config/mongodb.config';@Módulo({
importaciones: [
ConfigModule.forRoot({
cargar: [mongodbConfig],
esGlobal: verdadero
}),
NestGraphQLModule.forRootAsync({
conductor: conductor de apolo,
inyectar: [ConfigService],
fábrica de uso: asíncrono (configService: ConfigService) => ({
autoSchemaFile: unirse (proceso.cwd(), 'src/esquema.gql'),
installSubscriptionHandlers: verdadero,
sortSchema: verdadero,
patio de juegos: verdadero,
depuración: configService.get<booleano>("DEPURAR"),
cargas: FALSO,
}),
}),
MongooseModule.forRootAsync({
inyectar: [ConfigService],
fábrica de uso: asíncrono (configService: ConfigService) => ({
uri: configService.get('MONGO_URI')
})
}),
],
controladores: [AppController],
proveedores: [servicio de aplicaciones],
})
exportarclase Módulo de aplicación {}
Este módulo importa el Módulo GraphQL de @nestjs/graphql y el MongooseModule de @nestjs/mangosta que ayuda a conectarse a MongoDB. El AutoSchemaFile propiedad especifica la ubicación del archivo de esquema generado, y el sortSchema La propiedad asegura que ordena los campos alfabéticamente.
Esto es lo que su MongoDB configuración el archivo debe verse como:
importar { registrarse como } de'@nestjs/config';
/**
* Configuración de conexión de base de datos Mongo
*/
exportarpor defecto registrarse como ('mongodb', () => {
constante {
MONGO_URI
} = proceso.env;
devolver {
Uri: `${MONGO_URI}`,
};
});
Definición del esquema GraphQL
Una vez configuradas las conexiones de GraphQL y MongoDB, debe definir consultas y mutaciones de GraphQL para generar un esquema (esquema.gql) archivo.
Escribir consultas
En el enfoque de código primero, creas un modelo usando el Tipo de objeto decorador. Más adelante transformará este modelo en un tipo GraphQL.
Por ejemplo:
// libro.modelo.ts
importar { Campo, Tipo de objeto } de'@nestjs/graphql';
importar { Objeto, Esquema, SchemaFactory } de'@nestjs/mangosta';
importar { Documento } de'mangosta';exportartipo LibroDocumento = Libro y Documento;
@Tipo de objeto()
@Esquema()
exportarclase Libro {
@Campo()
título: cadena;@Campo()
autor: cadena;@Campo()
Fecha de Publicación: booleano;
}
exportarconstante BookSchema = SchemaFactory.createForClass (Libro);
GraphQL, de forma predeterminada, no puede usar los esquemas creados. Para hacerlos funcionales, necesita un servicio de resolución que contenga las funciones para ejecutar los tipos de GraphQL. Puedes hacerlo con el resolver decorador.
// libros.resolver.ts
importar { Resolución, Consulta, Mutación, Args, ID } de'@nestjs/graphql';
importar { Libro } de'./libro.modelo';
importar { Servicio de reserva } de'./servicio.de.libros';@Resolver(() => Libro)
exportarclase LibroResolver {
constructor(privado Servicio de libros de solo lectura: Servicio de libros) { }@Consulta(() => [Libro])
asíncrono libros(): Promesa{
devolvereste.bookService.findAll();
}
@Consulta(() => Libro)
asíncrono libro(@Args('identificación', { tipo: () => Hice: cadena): Promesa{
devolvereste.bookService.findOne (id);
}
}
Puede implementar el LibroServicio, importado arriba, de la siguiente manera:
// libros.servicio.ts
importar { Inyectable } de'@nestjs/común';
importar { Inyectar modelo } de'@nestjs/mangosta';
importar { Modelo } de'mangosta';
importar { Libro, LibroDocumento } de'./libro.modelo';@Inyectable()
exportarclase Reservar servicio {
constructor(@InyectarModelo(Nombre del libro) privado libroModelo: Modelo) { }asíncrono encuentra todos(): Promesa
{
devolvereste.modelo de libro.find().exec();
}
asíncrono encontrarUno (id: cadena): Promesa
{
devolvereste.bookModel.findById (id).exec();
}
}
También debe agregar el BookResolver a la lista de proveedores en libros.módulo.ts.
importar { Módulo } de"@nestjs/común";
importar { Módulo Mongoose } de"@nestjs/mangosta";
importar { Servicio de reserva } de'./servicio.de.libros';
importar { LibroResolver } de'./libros.resolver';
importar { Libro, BookSchema } de'./libro.modelo';@Módulo({
proveedores: [
servicio de libros,
LibroResolver
],
importaciones: [MongooseModule.forFeature([
{
nombre: Libro.nombre,
esquema: BookSchema,
},
]),
],
})
exportarclase LibrosMódulo {}
Trabajar con mutaciones
Mientras usa una consulta para recuperar datos en GraphQL, las mutaciones crean o actualizan datos en la base de datos. Para crear mutaciones, debe aceptar datos de los usuarios. El Tipo de entrada decorador, que convierte una clase en un tipo de entrada de GraphQL, resulta útil aquí.
// libro.entrada.ts
importar { Tipo de entrada, campo } de'@nestjs/graphql';@Tipo de entrada()
exportarclase LibroEntrada {
@Campo()
título: cadena;@Campo()
autor: cadena;
@Campo()
Fecha de Publicación: booleano
}
Ahora puede actualizar libros.resolver.ts para verse así:
importar { Resolución, Consulta, Mutación, Args, ID } de'@nestjs/graphql';
importar { Libro } de'./libro.modelo';
importar { Servicio de reserva } de'./servicio.de.libros';
importar { Entrada de libro } de'./libro.entrada';@Resolver(() => Libro)
exportarclase LibroResolver {
constructor(privado Servicio de libros de solo lectura: Servicio de libros) { }@Mutación(() => Libro)
asíncrono crearLibro(@Args('aporte') entrada: LibroEntrada): Promesa{
devolvereste.bookService.create (entrada);
}@Mutación(() => Libro)
asíncrono actualizarLibro(
@Args('identificación', { tipo: () => Hice: cadena,
@Args('aporte') entrada: entrada de libro,
): Promesa{
devolvereste.bookService.update (id, entrada);
}
@Mutación(() => Libro)
asíncrono eliminarLibro(@Args('identificación', { tipo: () => Hice: cadena): Promesa{
devolvereste.bookService.eliminar (id);
}
}
Y libros.servicio.ts como esto:
importar { Inyectable } de'@nestjs/común';
importar { Inyectar modelo } de'@nestjs/mangosta';
importar { Modelo } de'mangosta';
importar { Libro, LibroDocumento } de'./libro.modelo';@Inyectable()
exportarclase Reservar servicio {
constructor(@InyectarModelo(Nombre del libro) privado libroModelo: Modelo) { }asíncrono crear (libro: Libro): Promesa
{
constante libro nuevo = nuevoeste.bookModel (libro);
devolver nuevoLibro.guardar();
}asíncrono actualizar (id: cadena, libro libro): Promesa
{
devolvereste.bookModel.findByIdAndUpdate (id, libro, { nuevo: verdadero }).exec();
}
asíncronoborrar(identificación: cadena): Promesa
{
devolvereste.bookModel.findByIdAndDelete (id).exec();
}
}
El @Mutación decorador marca una función como un tipo de mutación y el @Args decorador toma cualquier entrada pasada a la función.
Finalmente, debe importar el LibrosMódulo en módulo de aplicación para hacerlo funcional. También debe pasar el LibrosMódulo a paraRootAsync como se ve a continuación.
importar { LibrosMódulo } de'./libros/libros.módulo';
/**
* otras importaciones
*/@Módulo({
importaciones: [
ConfigModule.forRoot({
cargar: [mongodbConfig],
esGlobal: verdadero
}),
NestGraphQLModule.forRootAsync({
conductor: conductor de apolo,
inyectar: [ConfigService],
fábrica de uso: asíncrono (configService: ConfigService) => ({
autoSchemaFile: unirse (proceso.cwd(), 'src/esquema.gql'),
installSubscriptionHandlers: verdadero,
sortSchema: verdadero,
patio de juegos: verdadero,
depuración: configService.get<booleano>("DEPURAR"),
cargas: FALSO,
}),
}),
MongooseModule.forRootAsync({
inyectar: [ConfigService],
fábrica de uso: asíncrono (configService: ConfigService) => ({
uri: configService.get('MONGO_URI')
})
}),
LibrosMódulo,
],
controladores: [AppController],
proveedores: [servicio de aplicaciones],
})
exportarclase Módulo de aplicación {}
Puede probar el código ejecutando inicio de ejecución de npm: dev en su terminal, y su aplicación debería comenzar con éxito en el puerto 3000.
Abierto servidor local: 3000/graphql en su navegador para mostrar el Grafiql interfaz donde se pueden probar consultas y mutaciones. Aquí hay un ejemplo que muestra una consulta:
Y aquí hay un ejemplo de una mutación:
Cree API eficientes con NestJS y GraphQL
Construir una API GraphQL en NestJS con MongoDB usando Mongoose implica definir un esquema para la API GraphQL, un esquema para el modelo Mongoose, un servicio para interactuar con la base de datos y un resolver para mapear las operaciones de GraphQL al servicio métodos.
NestJS tiene una funcionalidad integrada para crear API, incluidos decoradores para definir rutas, guardias para protegerlos y middlewares para manejar solicitudes y respuestas. También admite otras bases de datos como PostgreSQL, MySQL y SQLite, así como otras bibliotecas de GraphQL como Apollo y TypeGraphQL.