How to

#GraphQL #React #NestJS #Prisma #Senior #Mejores Prácticas

Mejores Prácticas de GraphQL para Principiantes: React, NestJS, Prisma

GraphQL es un poderoso lenguaje de consulta para tu API, y combinarlo con React, NestJS y Prisma puede crear una pila robusta y eficiente para el desarrollo web. Esta guía te llevará a través de las mejores prácticas, proporcionará ejemplos e introducirá herramientas para ayudarte a comenzar. También cubriremos cómo implementar la funcionalidad de registro y usar tokens para obtener información del usuario, dirigido a los usuarios de Yarn.

¿Por Qué GraphQL?

GraphQL proporciona una alternativa más eficiente y flexible que REST al permitir que los clientes soliciten exactamente los datos que necesitan. Esto reduce los problemas de sobrecarga y subcarga de datos y proporciona una mejor experiencia tanto para los desarrolladores como para los usuarios.

Configurando Tu Entorno

Antes de sumergirte en el código, asegúrate de tener instaladas las herramientas necesarias:

Creando el Backend con NestJS y Prisma

Paso 1: Inicializa el Proyecto de NestJS

Utilizo Yarn para la gestión de paquetes, pero puedes usar npm o pnpm si prefieres.

Comienza creando un nuevo proyecto NestJS:

yarn create @nestjs/core my-nestjs-app
cd my-nestjs-app
yarn add @nestjs/graphql @nestjs/apollo graphql apollo-server-express

Paso 2: Configura Prisma

Prisma es un conjunto de herramientas moderno para bases de datos que simplifica el acceso a bases de datos en aplicaciones de Node.js y TypeScript.

yarn add prisma @prisma/client
npx prisma init

Configura tu archivo prisma/schema.prisma para definir tus modelos de base de datos. Por ejemplo:

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

generator client {
  provider = "prisma-client-js"
}

model User {
  id        Int      @id @default(autoincrement())
  email     String   @unique
  password  String
  name      String?
  createdAt DateTime @default(now())
}

Ejecuta lo siguiente para migrar tu base de datos:

npx prisma migrate dev --name init

Paso 3: Implementa GraphQL en NestJS

Crea un módulo GraphQL y un resolver en NestJS:

nest g module graphql
nest g resolver graphql

En graphql/graphql.module.ts, configura GraphQL:

import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
import { join } from 'path';

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloDriverConfig>({
      driver: ApolloDriver,
      autoSchemaFile: join(process.cwd(), 'src/schema.gql'),
    }),
  ],
})
export class GraphqlModule {}

En graphql/graphql.resolver.ts, define tus resolvers:

import { Resolver, Query, Mutation, Args } from '@nestjs/graphql';
import { PrismaService } from '../prisma/prisma.service';

@Resolver()
export class GraphqlResolver {
  constructor(private prisma: PrismaService) {}

  @Query(() => String)
  async hello() {
    return '¡Hola Mundo!';
  }

  // Agrega las mutaciones de registro y obtención de información del usuario aquí
}

Paso 4: Agrega Registro y Obtención de Información del Usuario

Define tipos de GraphQL y resolvers para el registro y la obtención de información del usuario:

import { ObjectType, Field, ID } from '@nestjs/graphql';

@ObjectType()
export class User {
  @Field(() => ID)
  id: number;

  @Field()
  email: string;

  @Field()
  name?: string;
}

@Resolver(() => User)
export class UserResolver {
  constructor(private prisma: PrismaService) {}

  @Mutation(() => User)
  async signup(
    @Args('email') email: string,
    @Args('password') password: string,
    @Args('name') name?: string,
  ): Promise<User> {
    return this.prisma.user.create({
      data: {
        email,
        password, // hash esto en aplicaciones reales
        name,
      },
    });
  }

  @Query(() => User)
  async me(@Args('id') id: number): Promise<User> {
    return this.prisma.user.findUnique({ where: { id } });
  }
}

Configurando el Frontend con React

Paso 1: Inicializa el Proyecto de React

Crea un nuevo proyecto de React e instala las dependencias:

yarn create react-app my-react-app
cd my-react-app
yarn add @apollo/client graphql

Paso 2: Configura Apollo Client

Configura Apollo Client en tu aplicación React:

import React from 'react';
import { ApolloProvider, InMemoryCache, ApolloClient } from '@apollo/client';

const client = new ApolloClient({
  uri: 'http://localhost:3000/graphql',
  cache: new InMemoryCache(),
});

function App() {
  return (
    <ApolloProvider client={client}>
      <div className="App">
        <h1>Hola GraphQL</h1>
        {/* Agrega componentes para registro y obtención de información del usuario */}
      </div>
    </ApolloProvider>
  );
}

export default App;

Paso 3: Implementa el Registro y la Obtención de Información del Usuario

Crea un componente para el registro:

import React, { useState } from 'react';
import { gql, useMutation } from '@apollo/client';

const SIGNUP = gql`
  mutation Signup($email: String!, $password: String!, $name: String) {
    signup(email: $email, password: $password, name: $name) {
      id
      email
    }
  }
`;

function Signup() {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [name, setName] = useState('');
  const [signup] = useMutation(SIGNUP);

  const handleSubmit = async (e) => {
    e.preventDefault();
    try {
      const { data } = await signup({ variables: { email, password, name } });
      console.log('Usuario registrado:', data);
    } catch (error) {
      console.error('Error al registrarse:', error);
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="email"
        value={email}
        onChange={(e) => setEmail(e.target.value)}
        placeholder="Email"
      />
      <input
        type="password"
        value={password}
        onChange={(e) => setPassword(e.target.value)}
        placeholder="Contraseña"
      />
      <input
        type="text"
        value={name}
        onChange={(e) => setName(e.target.value)}
        placeholder="Nombre"
      />
      <button type="submit">Registrar</button>
    </form>
  );
}

export default Signup;

Crea un componente para obtener información del usuario:

import React, { useState } from 'react';
import { gql, useQuery } from '@apollo/client';

const GET_USER = gql`
  query Me($id: Int!) {
    me(id: $id) {
      id
      email
      name
    }
  }
`;

function FetchUser() {
  const [userId, setUserId] = useState('');
  const { data, loading, error } = useQuery(GET_USER, {
    variables: { id: parseInt(userId) },
    skip: !userId,
  });

  const handleFetchUser = (e) => {
    e.preventDefault();
    if (userId) {
      // Disparar consulta
    }
  };

  return (
    <div>
      <form onSubmit={handleFetchUser}>
        <input
          type="number"
          value={userId}
          onChange={(e) => setUserId(e.target.value)}
          placeholder="ID de Usuario"
        />
        <button type="submit">Obtener Información del Usuario</button>
      </form>
      {loading && <p>Cargando...</p>}
      {error && <p>Error al obtener información del usuario: {error.message}</p>}
      {data && (
        <div>
          <p>ID: {data.me.id}</p>
          <p>Email: {data.me.email}</p>
          <p>Nombre: {data.me.name}</p>
        </div>
      )}
    </div>
  );
}

export default FetchUser;

Conclusión

Siguiendo estas mejores prácticas y ejemplos, puedes usar GraphQL de manera eficiente con React, NestJS y Prisma. Esta pila te permite construir aplicaciones escalables y mantenibles. Recuerda siempre asegurar tus puntos finales y manejar adecuadamente datos sensibles como contraseñas y tokens.