¿Cómo construir una API GraphQL?

What is GraphQL Cover

En los últimos años, GraphQL se ha convertido en una opción popular para crear API complejas. Esto se debe a que elimina algunas de las limitaciones de las API REST tradicionales y hace que su API sea más flexible y eficiente.

En este artículo, analizaremos GraphQL, sus ventajas y desventajas, la terminología clave de GraphQL y compararemos las API de GraphQL con las API de REST. Además de eso, le enseñaremos cómo crear su propia API GraphQL en Back4app y conectarse a ella desde una interfaz Next.js.

Introducción a GraphQL

GraphQL es un lenguaje de consulta y un tiempo de ejecución del lado del servidor para desarrollar interfaces de programación de aplicaciones (API). Con GraphQL, los clientes pueden especificar exactamente qué datos necesitan de la API, en lugar de depender del backend para proporcionar un conjunto fijo de datos.

GraphQL es un enfoque moderno y eficiente para crear API rápidas y flexibles. Tiene un sistema de tipos integrado y se basa en un esquema fuertemente tipado que define los datos disponibles a través de la API.

Admite actualizaciones y suscripciones en tiempo real y permite a los desarrolladores obtener datos de múltiples fuentes de datos. Además de eso, facilita la evolución de las API al brindar a los desarrolladores la capacidad de desaprobar campos sin afectar las consultas o mutaciones existentes.

GraphQL puede usarse desde el inicio de un proyecto o integrarse en una API existente. Algunas empresas también lo combinan con REST y luego migran paso a paso.

Fue desarrollado internamente por Facebook en 2012 y luego de código abierto en 2015. GraphQL ha ganado popularidad con el auge de las aplicaciones de una sola página (SPA, del inglés “single-page applications”) y las aplicaciones móviles. Desde su lanzamiento, ha sido adoptado por muchos gigantes tecnológicos como GitHub, Airbnb, Pinterest y Shopify.

GraphQL frente a REST

GraphQL y REST son dos enfoques populares para crear API web.

REST (Representational State Transfer) es un estilo de arquitectura de software que describe la estructura de la web. Se introdujo en 2000 y ha sido el estándar de facto para crear API web durante más de una década.

Utiliza métodos HTTP como GET, POST, PUT, PATCH, y DELETE para manipular los recursos. Cada recurso está alojado en su punto final (consulte la imagen a continuación) y cada vez que solicitamos un recurso, se devuelve el “conjunto de datos” completo.

Esta arquitectura introdujo dos problemas. El primero es la obtención insuficiente (obtener muy pocos datos) y la obtención excesiva (obtener demasiados datos). Además, las API REST no nos permiten suscribirnos a los cambios de datos.

Aquí es donde entra GraphQL. GraphQL tiene un punto final único y nos permite consultar datos de múltiples fuentes de datos en una sola solicitud. Nos permite definir exactamente qué datos necesitamos. Además, GraphQL nos permite suscribirnos a los cambios de datos sin sondear el servidor. Hace que nuestra API sea más predecible y autodocumentada.

Al final, la elección entre GraphQL y REST dependerá de los requisitos específicos de su proyecto. Aunque GraphQL es excelente, puede presentar demasiada complejidad para proyectos simples.

REST API vs GraphQL API

Términos comunes de GraphQL

Veamos algunos de los términos comunes que puede encontrar al trabajar con GraphQL.

Tipo

GraphQL tiene un sistema de tipos y está fuertemente tipado. Viene con algunos tipos escalares incorporados como Int, Float, String, y Boolean, pero también le permite definir tipos personalizados.

Un tipo personalizado se puede definir así:

type User {
    username: String!
    password: String!
    friends: [User!]
}

Esquema

Un esquema es una descripción de los datos disponibles a través de una API de GraphQL. Incluye los tipos de objetos, sus campos y tipos de datos asociados, relaciones, consultas, mutaciones y más. Un esquema generalmente se define utilizando el lenguaje de definición de esquemas (SDL).

Un ejemplo de esquema

Resolver

Un resolver es una función que recupera los datos de un campo en particular en una consulta de GraphQL. Las funciones de resolución son responsables de obtener los datos de una fuente de datos y devolverlos en el formato esperado.

Consulta

Una consulta es una solicitud de datos de solo lectura de una API de GraphQL. Puede pensar en las consultas como solicitudes GET en la API REST.

Ejemplo:

query GetUser {
    user(id: "Wfx8o2AZrE") {
        id
        username
        fullName
    }
}

Esta consulta devuelve la lista de todos los usuarios.

Mutación

Una mutación es una solicitud para manipular los datos en una API de GraphQL. Puede pensar en las mutaciones como solicitudes POST/PUT/PATCH/DELETE en la API REST. Las mutaciones también pueden definir qué datos se devuelven.

Ejemplo:

mutation CreateAuthor {
  createAuthor(input: {fields: {firstName: "William", lastName: "Shakespeare"}}) {
    author {
      id
      createdAt
    }
  }
}

Esta mutación crea un nuevo autor y devuelve la identificación del autor y createdAt.

Suscripción

Una suscripción es una solicitud de actualizaciones en tiempo real de una API de GraphQL. Las suscripciones permiten a los clientes recibir actualizaciones tan pronto como estén disponibles, sin sondear el servidor.

Example:

subscription OnPostCreate($postID: ID!) {
  userAdded(postID: $postID) {
    id
    user
    content
  }
}

Esta suscripción se llama cuando se crea una nueva publicación.

¿Cómo funciona GraphQL?

Para implementar una API de GraphQL, deberá realizar los siguientes pasos:

  1. Describir sus datos usando un esquema
  2. Conectar resolutores a fuentes de datos
  3. Escribir consultas y mutaciones
  4. Obtener resultados predecibles

Al usar Back4app o un servicio similar, la mayor parte de este trabajo se abstraerá. A medida que crea los modelos de base de datos, Back4app generará automáticamente el esquema y la documentación de GraphQL. Más sobre esto en la parte práctica del tutorial.

¿Cuáles son las ventajas de GraphQL?

GraphQL es fácil de aprender, los usuarios pueden agregar datos de múltiples fuentes y es un lenguaje moderno para su API.

Esquema

La API de GraphQL se basa en un esquema fuertemente tipado. Esto le permite detectar errores de tipo y fallas en tiempo de compilación en lugar de en tiempo de ejecución. Además, las API de GraphQL son introspectivas, lo que significa que pueden proporcionar información sobre sí mismas sin depender de ninguna documentación externa.

Obtención de datos flexible y eficiente

Las API de GraphQL son extremadamente flexibles ya que permiten a los clientes especificar exactamente lo que necesitan. Esto resuelve el problema de la obtención insuficiente y excesiva y reduce la cantidad de solicitudes de API. Menos solicitudes de API dan como resultado un mejor rendimiento.

Actualizaciones de API

Con GraphQL, puede integrar sin problemas nuevos campos y tipos sin afectar las consultas actuales. Los campos en desuso y obsoletos también se pueden ocultar de las herramientas. Las API de GraphQL brindan a las aplicaciones acceso constante a nuevas funciones y fomentan el desarrollo de un código de servidor más limpio y sostenible.

Fuente única de la verdad

Un esquema GraphQL establece una única fuente de verdad en una aplicación GraphQL. Ofrece a una organización una manera fácil de administrar toda su API.

Extensiones GraphQL

GraphQL está respaldado por una gran comunidad de desarrolladores de GraphQL y viene con muchas extensiones de código abierto. Las extensiones simplifican algunas de las tareas comunes de la API, como la paginación, el almacenamiento en caché, la supervisión del rendimiento, etc.

¿Cuáles son las desventajas de GraphQL?

Complejidad

GraphQL traslada gran parte del trabajo de una consulta de datos al lado del servidor, lo que hace que los backend sean más complejos. Además de eso, el lenguaje de consulta y las definiciones de esquema pueden requerir más planificación y mantenimiento por adelantado.

Curva de aprendizaje

GraphQL tiene una curva de aprendizaje más pronunciada que REST. Además, los desarrolladores de GraphQL suelen ser más caros y difíciles de encontrar que los desarrolladores de REST.

Falta de estandarización

Una de las principales críticas a GraphQL es la falta de estandarización en su implementación. Las API REST tienen un conjunto bien establecido de principios y mejores prácticas, mientras que la documentación de GraphQL solo proporciona algunos consejos generales sobre cómo implementar cosas. Esto puede generar incoherencias y confusión en la forma en que se diseñan y utilizan las API de GraphQL.

Seguridad

Lo mejor de GraphQL es que los clientes pueden solicitar exactamente lo que necesitan, pero, por otro lado, eso podría ser un riesgo potencial de seguridad. Es importante validar y desinfectar adecuadamente la entrada del usuario para evitar que se ejecuten consultas maliciosas.

¿Cómo construir una API GraphQL?

Esta sección del artículo analiza cómo crear una API de GraphQL con Back4app y conectarse a ella desde una interfaz de Next.js.

Requisitos previos

  • Experiencia con JavaScript ES6
  • Experiencia con React y Next.js
  • Comprensión básica de GraphQL

¿Qué es Back4app?

Back4app es una solución excepcional de backend como servicio (BaaS) que funciona sobre software de código abierto.

La plataforma proporciona una amplia gama de características que permiten a los usuarios un desarrollo más fácil y rápido de aplicaciones web y móviles. Permite a las empresas centrarse en su lógica empresarial sin tener que preocuparse por el backend o la infraestructura subyacente.

Back4app viene con un tablero fácil de usar que está repleto de funciones y una interfaz de línea de comandos (CLI). También proporciona kits de desarrollo de software (SDK) para varias herramientas populares como Node.js, Flutter, React Native, Android, Angular, iOS y más.

Back4app sigue un modelo de precios sencillo que puede satisfacer las necesidades de cualquier aplicación. También ofrecen un plan gratuito (no se requiere tarjeta de crédito) que es excelente para realizar pruebas y prototipos.

¿Desea saber más sobre Back4app? Consulte ¿Por qué usar Back4app?

Introducción al proyecto

Construiremos una aplicación de COSAS POR HACER web simple. La aplicación estará compuesta por dos partes: el backend y el frontend. El backend funcionará con una API de GraphQL y se implementará en Back4app. La interfaz, por otro lado, se escribirá en TypeScript utilizando el marco Next.js. Para conectar el frontend con el backend, usaremos Apollo Client.

La aplicación final se verá así:

back4app-graphql Project Preview

Backend

Crear aplicación Back4app

Para continuar con los siguientes pasos, deberá tener una cuenta Back4app. Si ya tiene uno, por favor inicie sesión. De lo contrario, no dude en registrarse para obtener una cuenta gratuita.

Para utilizar Back4app, el primer paso es crear una aplicación. Una vez que haya iniciado sesión en su tablero, podrá ver una lista de sus aplicaciones actuales. Para crear una nueva aplicación, haga clic en “Crear una nueva aplicación”.

Back4app App Creation

Como estamos construyendo una API de GraphQL, elija la opción “Backend como servicio” y especifique un nombre único para su aplicación. Además, elija “NoSQL” como tipo de base de datos.

Espere pacientemente a que Back4app configure todo lo necesario para su aplicación, incluida la base de datos, la capa de la aplicación, el escalado, las copias de seguridad y la seguridad.

Una vez completada la configuración, se le dirigirá al panel de control de su aplicación.

Back4app App Created

Definir modelos de base de datos

Como estamos creando una aplicación de COSAS POR HACER simple, solo necesitaremos un modelo de base de datos.

Para comenzar, vaya a su panel de Back4app y busque la opción “Base de datos” en la barra lateral. Desde allí, elija “Crear una clase” y asígnele el nombre “Tarea”. Asegúrese de seleccionar “Lectura y escritura públicas habilitadas” y luego haga clic en “Crear clase y agregar columnas”.

Back4app Define Model

Incluya las columnas siguientes:

+-----------+------------------+---------------+----------+
| Data type | Name             | Default value | Required |
+-----------+------------------+---------------+----------+
| String    | name             | <leave blank> | yes      |
+-----------+------------------+---------------+----------+
| String    | description      | <leave blank> | no       |
+-----------+------------------+---------------+----------+
| Boolean   | isDone           | false         | no       |
+-----------+------------------+---------------+----------+

Después de crear su modelo de base de datos, notará que cuatro columnas de base de datos se agregaron automáticamente:

  1. objectId es la clave principal de su objeto
  2. updatedAt es la marca de tiempo de la última actualización
  3. createdAt es la marca de tiempo de la creación
  4. ACL define la “Lista de control de acceso”

Téngalos en cuenta, ya que los necesitaremos más adelante en el tutorial cuando trabaje en consultas y mutaciones de GraphQL.

Para familiarizarse con el tablero de Back4app, intente agregar dos tareas de muestra, por ejemplo:

+-----------------+----------------------------------------+--------+
| name            | description                            | isDone |
+-----------------+----------------------------------------+--------+
| GraphQL backend | Create a GraphQL backend via Back4app. | false  |
+-----------------+----------------------------------------+--------+
| Learn GraphQL   | Learn the basics of GraphQL.           | true   |
+-----------------+----------------------------------------+--------+

Consola API de GraphQL

GraphQL API Console nos permite probar las consultas y mutaciones de GraphQL antes de implementarlas en el código. Para acceder a la consola, seleccione “API” en la barra lateral y luego “Consola > GraphQL”.

Back4app GraphQL Console

La consola es extremadamente fácil de usar. En el lado izquierdo, podemos ingresar nuestras consultas y mutaciones personalizadas y luego los resultados se muestran a la derecha.

Para verificar si todo está funcionando, ejecute la siguiente consulta:

query CheckHealth {
    health
}

Debería obtener la siguiente respuesta JSON:

{
  "data": {
    "health": true
  }
}

Una de las mejores cosas de Back4app es que está basado en Parse. Cuando creamos nuestro modelo de base de datos, Parse configuró automáticamente GraphQL para nosotros. Eso incluye generar un esquema GraphQL, documentos, etc.

Intentemos enumerar las tareas y sus detalles de la base de datos:

query GetTasks {
  tasks {
    count
    edges {
      node {
        id
        name
        description
        isDone
      }
    }
  }
}

Debería obtener una respuesta similar:

{
  "data": {
    "tasks": {
      "count": 2,
      "edges": [
        {
          "node": {
            "id": "VGFzazpXQkJzSkRtV2xU",
            "name": "GraphQL backend",
            "description": "Create a GraphQL backend via Back4app.",
            "isDone": false
          }
        },
        {
          "node": {
            "id": "VGFzazpnM2lhNzdwUXBp",
            "name": "Learn GraphQL",
            "description": "Learn the basics of GraphQL.",
            "isDone": true
          }
        }
      ]
    }
  }
}

Obtener un objeto específico, crear objetos, actualizarlos, etcétera, se realiza de manera similar. No entraré demasiado en detalles ahora, ya que explicaré estas consultas y mutaciones más adelante en el tutorial. Además, los documentos de Back4app cubren bien estos temas:

  1. Creando un objeto
  2. Obteniendo un objeto
  3. Encontrando objetos
  4. Actualización de un objeto
  5. Eliminación de un objeto
  6. Autenticación

Eso es todo por la parte de backend. En la siguiente sección, comenzaremos a trabajar en el frontend.

Frontend

Crear aplicación NEXT

La forma más sencilla de iniciar un proyecto Next.js es mediante la utilidad create-next-app. Abra su terminal y ejecute el siguiente comando:

$ yarn create next-app

√ What is your project named? ... back4app-graphql
√ Would you like to use TypeScript with this project? ... No
√ Would you like to use ESLint with this project? ... Yes
√ Would you like to use the `src/` directory with this project? ... No
√ Would you like to use the experimental `app/` directory with this project? ... No
√ What import alias would you like configured? ... @/*

Successfully created a Next.js app.

A continuación, ejecute el servidor de desarrollo:

$ yarn dev

Navegue a http://localhost:3000 y debería ver la página de destino predeterminada de Next.js.

NextJS Default Landing Page

ChakraUI

Para acelerar y simplificar el proceso de creación de UI/UX, usaremos ChakraUI. Chakra UI es una biblioteca de componentes simple, modular y accesible que le brinda todo lo que necesita para crear sus aplicaciones React.

En caso de que tenga algún problema, consulte ChakraUI: Primeros pasos con Next.js.

Para instalarlo ejecute:

yarn add @chakra-ui/react @emotion/react @emotion/styled framer-motion

Luego, navegue a su _pages/app.tsx y envuelva su aplicación con el ChakraProvider así:

// pages/_app.tsx

import "../styles/globals.css";
import type {AppProps} from "next/app";
import {ChakraProvider} from "@chakra-ui/react";

export const theme = extendTheme({});

function MyApp({ Component, pageProps }: AppProps) {
  return (
    <ChakraProvider theme={theme}>
      <Component {...pageProps} />
    </ChakraProvider>
  );
}

export default MyApp;

No olvide importar el ChakraProvider:

import {ChakraProvider} from "@chakra-ui/provider";

Para evitar destellos de color aleatorios, asegúrese de cargar el script de modo de color antes que el contenido. Para hacer eso, puede utilizar _document.js así:

// pages/_document.tsx

import {ColorModeScript} from "@chakra-ui/react";
import { Html, Head, Main, NextScript } from "next/document";
import {theme} from "@/pages/_app";

export default function Document() {
  return (
    <Html lang='en'>
      <Head />
      <body>
        <ColorModeScript initialColorMode={theme.config.initialColorMode} />
        <Main />
        <NextScript />
      </body>
    </Html>
  );
}

Genial, ha instalado correctamente ChakraUI.

Interfaz de usuario

Avanzando, vamos a crear la interfaz de usuario. Nuestra aplicación web tendrá las siguientes dos páginas:

  1. / muestra la lista de tareas
  2. create/ muestra el formulario para crear tareas

Comience reemplazando pages/index.tsx con los siguientes contenidos:

// pages/index.tsx

import type {NextPage} from "next";
import {
    Button, Card, CardBody, Container,
    Heading, HStack, Stack, Text, VStack
} from "@chakra-ui/react";
import Link from "next/link";

let data = {
  "tasks": {
    "count": 2,
    "edges": [
      {
        "node": {
          "id": "VGFzazpXQkJzSkRtV2xU",
          "name": "GraphQL backend",
          "description": "Create a GraphQL backend via Back4app.",
          "isDone": false
        }
      },
      {
        "node": {
          "id": "VGFzazpnM2lhNzdwUXBp",
          "name": "Learn GraphQL",
          "description": "Learn the basics of GraphQL.",
          "isDone": true
        }
      }
    ]
  }
};

const ListPage: NextPage = () => {

  const handleMarkAsDone = async (id: string, isDone: boolean) => {
    console.log("TODO: mark task as done and refetch");
  };

  const handleDelete = async (id: string) => {
    console.log("TODO: delete task and refetch");
  };

  return (
    <>
      <Container maxWidth="container.lg">
        <HStack w="fill" justifyContent="space-between" mt={8} mb={4}>
          <Heading as="h1" size="lg">back4app-graphql</Heading>
          <Link href="/create">
            <Button size="sm" colorScheme="blue">
              Create task
            </Button>
          </Link>
        </HStack>
        <VStack spacing={4}>
          {data.tasks.edges.map((edge) => {
            let task = edge.node;
            return (
              <Card key={task.id} w="100%">
                <CardBody>
                  <Stack direction="column">
                    <Heading as="h2" size="md">
                      {task.isDone ? "✔️" : "❌"}{" "}
                      {task.name}
                    </Heading>
                    <Text>
                      {task.description}
                    </Text>
                    <Stack direction="row" pt={2}>
                      <Button size="sm" colorScheme="blue" onClick={() => handleMarkAsDone(task.id, task.isDone)}>
                        Toggle done
                      </Button>
                      <Button size="sm" colorScheme="red" onClick={() => handleDelete(task.id)}>
                        Delete
                      </Button>
                    </Stack>
                  </Stack>
                </CardBody>
              </Card>
            );
          })}
        </VStack>
      </Container>
    </>
  );
};

export default ListPage;
  1. Usamos ChakraUI para diseñar la interfaz de usuario.
  2. Las tareas se cargan actualmente desde la matriz estática denominada data.
  3. Más adelante utilizaremos handleMarkAsDone() y handleDelete() para enviar solicitudes de la API de GraphQL.

A continuación, cree un archivo create.tsx dentro de la carpeta de páginas con el siguiente contenido:

// pages/create.tsx

import type {NextPage} from "next";
import {
  Button, Card, CardBody, CardHeader, Container, FormControl,
  FormLabel, Heading, HStack, Input, Stack, Switch, Text
} from "@chakra-ui/react";
import Link from "next/link";
import {useState} from "react";
import {useRouter} from "next/router";

const CreatePage: NextPage = () => {
  const router = useRouter();

  const [name, setName] = useState("");
  const [description, setDescription] = useState("");
  const [isDone, setIsDone] = useState(false);

  const [formError, setFormError] = useState("");

  const handleSubmit = (event) => {
    event.preventDefault();

    if (!name || !description) {
      setFormError("Please enter the title and the description.");
      return;
    }

    console.log("TODO: call the GraphQL API and redirect");
  };

  return (
    <>
      <Container maxWidth="container.lg">
        <HStack w="fill" justifyContent="space-between" mt={8} mb={4}>
          <Heading as="h1" size="lg">back4app-graphql</Heading>
          <Link href="/">
            <Button size="sm" colorScheme="blue">
              View list
            </Button>
          </Link>
        </HStack>
        <Card>
          <CardHeader>
            <Stack direction="column">
              <Heading as="h2" size="md">Create task</Heading>
              <Text>
                Fill out the form and press &quot;Create&quot; to create a new task.
              </Text>
            </Stack>
          </CardHeader>
          <CardBody>
            <form onSubmit={handleSubmit}>
              <Stack direction="column">
                {formError && <Text color="red.500" fontWeight="bold">{formError}</Text>}
                <FormControl>
                  <FormLabel>Name</FormLabel>
                  <Input type="text" value={name} onChange={(event) => setName(event.target.value)}/>
                </FormControl>
                <FormControl>
                  <FormLabel>Description</FormLabel>
                  <Input type="text" value={description} onChange={(event) => setDescription(event.target.value)}/>
                </FormControl>
                <FormControl display="flex" alignItems="center">
                  <FormLabel mb="0">
                    Is done?
                  </FormLabel>
                  <Switch isChecked={isDone} onChange={() => setIsDone(!isDone)}/>
                </FormControl>
                <Button size="sm" colorScheme="blue" type="submit">Create task</Button>
              </Stack>
            </form>
          </CardBody>
        </Card>
      </Container>
    </>
  );
};

export default CreatePage;
  1. Nuevamente usamos componentes de ChakraUI para crear la interfaz de usuario.
  2. Creamos un formulario controlado por React para crear tareas.
  3. La función handleSubmit() se utilizará más adelante para enviar una solicitud de API.

Vuelva a iniciar su servidor web y visite su aplicación web en http://localhost:3000. Debería ver las dos tareas codificadas. A continuación, haga clic en “Crear tarea” para ver el formulario de creación de tareas.

Back4app GraphQL Create Task

Cliente GraphQL

Para conectarse a una API GraphQL desde la interfaz, primero debe instalar un cliente GraphQL. Le sugiero que opte por Apollo Client, ya que es fácil de configurar y no requiere mucho código repetitivo.

Comience instalando @apollo/client y graphql:

$ yarn add @apollo/client graphql

Para inicializar el cliente, deberá proporcionar sus credenciales API Back4app. La forma más fácil de obtener sus credenciales es navegar a su Consola GraphQL y tomar nota de los encabezados.

Back4app GraphQL Credentials

Dado que no desea exponer sus claves API en el código fuente, cree un archivo.env.local en la raíz del proyecto con los siguientes contenidos:

# .env.local

NEXT_PUBLIC_PARSE_APPLICATION_ID=<YOUR_PARSE_APP_ID>
NEXT_PUBLIC_PARSE_MASTER_KEY=<YOUR_PARSE_MASTER_KEY>
NEXT_PUBLIC_PARSE_CLIENT_KEY=<YOUR_PARSE_CLIENT_KEY>

Luego, navegue a pages/_app.tsx e inicialice el cliente Apollo, luego envuelva su aplicación con ApolloProvider así:

// pages/_app.tsx

// ...
import {ApolloClient, ApolloProvider, InMemoryCache} from "@apollo/client";

const client = new ApolloClient({
  uri: "https://parseapi.back4app.com/graphql",
  headers: {
    "X-Parse-Application-Id": process.env.NEXT_PUBLIC_PARSE_APPLICATION_ID,
    "X-Parse-Master-Key": process.env.NEXT_PUBLIC_PARSE_MASTER_KEY,
    "X-Parse-Client-Key": process.env.NEXT_PUBLIC_PARSE_CLIENT_KEY,
  },
  cache: new InMemoryCache(),
});

function MyApp({ Component, pageProps }: AppProps) {
  return (
    <ChakraProvider theme={theme}>
      <ApolloProvider client={client}>
        <Component {...pageProps} />
      </ApolloProvider>
    </ChakraProvider>
  );
}

Espere a que su interfaz se vuelva a compilar, luego visite su aplicación web y verifique la consola en busca de errores. La ausencia de errores significa que la conexión se ha realizado correctamente.

Consultas y mutaciones de GraphQL

Lo último que tiene que hacer es definir sus consultas y mutaciones GraphQL y luego llamarlas desde su código React.

Para habilitar la asistencia de código GraphQL en su IDE, vaya a la consola Back4app GraphQL, seleccione “Esquema” en la barra lateral y descárguelo como SDL. Luego, cree un nuevo archivo llamado schema.graphql en la raíz del proyecto y pegue el contenido de SDL.

Primero, navegue a pages/index.tsx y agregue las siguientes consultas después de las importaciones:

// pages/index.tsx

const GET_TASKS = gql`
  query GetTasks {
    tasks {
      count
      edges {
        node {
          id
          name
          description
          isDone
        }
      }
    }
  }
`;

const UPDATE_TASK = gql`
  mutation UpdateTask($id: ID!, $isDone: Boolean!) {
    updateTask(input: { id: $id, fields: { isDone: $isDone } }) {
      task {
        isDone
        updatedAt
      }
    }
  }
`;

const DELETE_TASK = gql`
  mutation DeleteTask($id: ID!) {
    deleteTask(input: { id: $id }) {
      task {
        id
      }
    }
  }
`;

Estas tres consultas se explican por sí mismas. El primero devuelve una lista de todas las tareas, el segundo actualiza la propiedad isDone de una tarea específica y el tercero elimina una tarea específica.

A continuación, modifique la parte superior de ListPage así:

// pages_index.tsx

// ...

const ListPage: NextPage = () => {

  const {loading, error, data, refetch} = useQuery(GET_TASKS);
  const [deleteTask] = useMutation(DELETE_TASK);
  const [updateTask] = useMutation(UPDATE_TASK);

const handleMarkAsDone = async (id: string, isDone: boolean) => {
    try {
      const updateTaskResponse = await updateTask({
        variables: {id: id, isDone: !isDone}
      });
      console.debug(updateTaskResponse);
      refetch();
    } catch (error) {
      console.error(error);
    }
  };

  const handleDelete = async (id: string) => {
    try {
      const deleteTaskResponse = await deleteTask({
        variables: {id: id},
      });
      console.debug(deleteTaskResponse);
      refetch();
    } catch (error) {
      console.error(error);
    }
  };

  if (error) return <p>Oops, something went wrong.</p>;
  if (loading) return <Spinner/>;

  // ...
};

export default ListPage;
  1. Usamos useQuery() para ejecutar la consulta GET_TASKS y almacenar el resultado.
  2. Usamos useMutation() para definir las mutaciones de GraphQL.
  3. Actualizamos handleMarkAsDone() y handleDelete() para utilizar los ganchos de mutación.

Avanzando, modifique pages/create.tsx de manera similar:

const CREATE_TASK = gql`
  mutation CreateTask($name: String!, $description: String, $isDone: Boolean!) {
    createTask(
      input: {
        fields: { name: $name, description: $description, isDone: $isDone }
      }
    ) {
      task {
        id
      }
    }
  }
`;

const CreatePage: NextPage = () => {

  // ...

  const [createTask] = useMutation(CREATE_TASK);

  const handleSubmit = (event) => {
    event.preventDefault();

    if (!name || !description) {
      setFormError("Please enter the title and the description.");
      return;
    }

    createTask({
      variables: {name: name, description: description, isDone: isDone}
    }).then(response => {
      router.push("/");
    });
  };

  // ...
};

export default CreatePage;

No se olvide de la importación:

import {gql, useMutation, useQuery} from "@apollo/client";

¡Genial, eso es todo!

Vuelva a iniciar su servidor de desarrollo y visite su aplicación web. Compruebe si las tareas se cargan desde la base de datos, intente crear una nueva tarea, márquela como completada y elimínela.

Conclusión

En conclusión, GraphQL es una buena opción para crear API complejas debido a sus capacidades de consulta flexibles y recuperación de datos eficiente. Si bien tiene muchas ventajas sobre la API REST tradicional, existen algunos inconvenientes que debe tener en cuenta al iniciar un proyecto.

En este artículo, analizamos las ventajas y desventajas de GraphQL, lo comparamos con las API REST y presentamos parte de la terminología clave de GraphQL. Ahora debería poder crear su propia API GraphQL simple en Back4app y conectarse a ella desde una interfaz de JavaScript.

Puede obtener el código fuente final del repositorio de GitHub.

Preguntas frecuentes

¿Qué es GraphQL?

GraphQL es un lenguaje de consulta y un tiempo de ejecución del lado del servidor para desarrollar API potentes y flexibles.

¿Cuáles son las principales diferencias entre REST y GraphQL?

REST es un enfoque estandarizado y simple para crear servicios web, mientras que GraphQL ofrece capacidades de consulta más flexibles y elimina la obtención insuficiente y excesiva de datos.

¿Cuáles son los términos de GraphQL comúnmente utilizados?

– El esquema es una descripción de los datos disponibles a través de una API de GraphQL. 
– Resolver es una función que recupera los datos de un campo en particular en una consulta de GraphQL. 
– Consulta es una solicitud de datos de solo lectura de una API de GraphQL. 
– La mutación es una solicitud para manipular los datos en una API de GraphQL. 
– La suscripción es una solicitud de actualizaciones en tiempo real de una API de GraphQL.

¿Cómo construir una API GraphQL?

1. Crea una cuenta gratuita en Back4app
2. Diseñar los modelos de base de datos.
3. Escriba las consultas y mutaciones a través de Back4app GraphQL API Console.
4. Instale un cliente GraphQL (como Apollo o Relay) en su proyecto frontend.
5. Inicialice el cliente y conéctese a la API de GraphQL.


Leave a reply

Your email address will not be published.