En este módulo, aprenderemos cómo conectar un servidor GraphQL a una base de datos. Este es un paso crucial para cualquier aplicación que necesite almacenar y recuperar datos de manera eficiente. Exploraremos cómo configurar la conexión, realizar consultas y mutaciones, y manejar errores comunes.

Objetivos de Aprendizaje

  • Configurar una conexión a una base de datos desde un servidor GraphQL.
  • Realizar consultas y mutaciones a la base de datos.
  • Manejar errores comunes en la conexión a la base de datos.

  1. Configuración de la Conexión a la Base de Datos

Paso 1: Instalación de Dependencias

Para este ejemplo, utilizaremos Node.js con Express y una base de datos PostgreSQL. Necesitaremos instalar las siguientes dependencias:

npm install express express-graphql graphql pg pg-hstore sequelize

Paso 2: Configuración de Sequelize

Sequelize es un ORM (Object-Relational Mapping) para Node.js que facilita la interacción con bases de datos SQL. Configuraremos Sequelize para conectarnos a nuestra base de datos PostgreSQL.

// db.js
const { Sequelize } = require('sequelize');

const sequelize = new Sequelize('database', 'username', 'password', {
  host: 'localhost',
  dialect: 'postgres',
});

module.exports = sequelize;

Paso 3: Definición de Modelos

Definimos nuestros modelos de datos utilizando Sequelize. Por ejemplo, un modelo de Usuario podría verse así:

// models/User.js
const { DataTypes } = require('sequelize');
const sequelize = require('../db');

const User = sequelize.define('User', {
  id: {
    type: DataTypes.INTEGER,
    autoIncrement: true,
    primaryKey: true,
  },
  name: {
    type: DataTypes.STRING,
    allowNull: false,
  },
  email: {
    type: DataTypes.STRING,
    allowNull: false,
    unique: true,
  },
});

module.exports = User;

Paso 4: Sincronización de la Base de Datos

Sincronizamos nuestros modelos con la base de datos para asegurarnos de que las tablas se crean correctamente.

// sync.js
const sequelize = require('./db');
const User = require('./models/User');

sequelize.sync({ force: true }).then(() => {
  console.log('Database & tables created!');
});

  1. Realización de Consultas y Mutaciones

Consultas

Para realizar consultas, definimos resolvers que interactúan con nuestros modelos de Sequelize.

// resolvers.js
const User = require('./models/User');

const resolvers = {
  Query: {
    users: async () => {
      return await User.findAll();
    },
    user: async (_, { id }) => {
      return await User.findByPk(id);
    },
  },
};

module.exports = resolvers;

Mutaciones

Las mutaciones permiten modificar los datos en la base de datos.

// resolvers.js
const resolvers = {
  Mutation: {
    createUser: async (_, { name, email }) => {
      return await User.create({ name, email });
    },
    updateUser: async (_, { id, name, email }) => {
      const user = await User.findByPk(id);
      if (!user) throw new Error('User not found');
      user.name = name;
      user.email = email;
      await user.save();
      return user;
    },
    deleteUser: async (_, { id }) => {
      const user = await User.findByPk(id);
      if (!user) throw new Error('User not found');
      await user.destroy();
      return user;
    },
  },
};

module.exports = resolvers;

  1. Manejo de Errores Comunes

Error de Conexión

Un error común es la incapacidad de conectarse a la base de datos. Asegúrate de que los detalles de conexión (nombre de la base de datos, usuario, contraseña, host) sean correctos.

sequelize.authenticate()
  .then(() => {
    console.log('Connection has been established successfully.');
  })
  .catch(err => {
    console.error('Unable to connect to the database:', err);
  });

Error de Validación

Los errores de validación ocurren cuando los datos no cumplen con las restricciones definidas en el modelo.

try {
  await User.create({ name: '', email: 'invalid-email' });
} catch (error) {
  console.error('Validation error:', error);
}

Ejercicio Práctico

Ejercicio 1: Crear y Consultar Usuarios

  1. Crear Usuarios: Implementa una mutación para crear un nuevo usuario.
  2. Consultar Usuarios: Implementa una consulta para obtener todos los usuarios.

Solución

# schema.graphql
type User {
  id: ID!
  name: String!
  email: String!
}

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

type Mutation {
  createUser(name: String!, email: String!): User
  updateUser(id: ID!, name: String, email: String): User
  deleteUser(id: ID!): User
}
// server.js
const express = require('express');
const { graphqlHTTP } = require('express-graphql');
const { buildSchema } = require('graphql');
const resolvers = require('./resolvers');
const schema = buildSchema(`
  type User {
    id: ID!
    name: String!
    email: String!
  }

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

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

const app = express();

app.use('/graphql', graphqlHTTP({
  schema: schema,
  rootValue: resolvers,
  graphiql: true,
}));

app.listen(4000, () => console.log('Server running on http://localhost:4000/graphql'));

Conclusión

En esta sección, hemos aprendido cómo conectar un servidor GraphQL a una base de datos utilizando Sequelize. Hemos cubierto la configuración de la conexión, la definición de modelos, la realización de consultas y mutaciones, y el manejo de errores comunes. Con estos conocimientos, estás preparado para manejar datos en tu aplicación GraphQL de manera eficiente y segura.

En el próximo módulo, exploraremos estrategias avanzadas de obtención de datos y cómo optimizar el rendimiento de nuestras consultas.

© Copyright 2024. Todos los derechos reservados