Una introducción completa a Apollo, el kit de herramientas GraphQL

Apollo es un conjunto de herramientas para crear un servidor GraphQL y consumir una API GraphQL. Exploremos Apollo en detalle, tanto Apollo Client como Apollo Server.

The Apollo Logo

Introducción a Apolo

En los últimos añosGraphQLse hizo muy popular como un enfoque alternativo para la creación de una API sobre REST.

GraphQL es una excelente manera de permitir que el cliente decida qué datos quiere que se transmitan a través de la red, en lugar de que el servidor envíe un conjunto fijo de datos.

Además, le permite especificar recursos anidados, reduciendo mucho el ir y venir que a veces se requiere cuando se trata de API REST.

Apollo es un equipo y una comunidad que se basa en GraphQL y proporciona diferentes herramientas que lo ayudan a construir sus proyectos.

Las herramientas proporcionadas por Apollo son principalmente 3:Cliente,Servidor,Motor.

Cliente Apollolo ayuda a consumir una API GraphQL, con soporte para las tecnologías web frontend más populares, incluida React,Vue, Angular, Ember, Meteor y más, y desarrollo nativo en iOS y Android.

Servidor Apolloes la parte del servidor de GraphQL, que interactúa con su backend y envía respuestas a las solicitudes del cliente.

Motor Apoloes una infraestructura alojada (SAAS) que actúa como intermediario entre el cliente y su servidor, proporcionando almacenamiento en caché, informes de rendimiento, medición de carga, seguimiento de errores, estadísticas de uso del campo de esquema, estadísticas históricas y muchas más ventajas. Actualmente es gratis hasta 1 millón de solicitudes por mes, y es la única parte de Apollo que no es de código abierto y gratuito, y proporciona fondos para la parte de código abierto del proyecto.

Vale la pena señalar que esas 3 herramientas no están vinculadas entre sí de ninguna manera, y puede usar solo Apollo Client para interactuar con una API de terceros, o servir una API usando Apollo Server sin tener un cliente, por ejemplo.

Es todocompatible con la especificación estándar GraphQL, por lo que no hay tecnología patentada o incompatible en Apollo.

Pero es muy conveniente tener todas esas herramientas juntas bajo un solo techo, una suite completa para todas sus necesidades relacionadas con GraphQL.

Apollo se esfuerza por ser fácil de usar y fácil de contribuir.

Apolo se centra enmanteniendo las cosas simples. Esto es algo clave para el éxito de una tecnología que quiere volverse popular, ya que alguna tecnología, marco o biblioteca puede ser excesiva para el 99% de las pequeñas o medianas empresas, y simplemente adecuada para las grandes empresas con necesidades muy complejas.

Cliente Apollo

Cliente Apolloes el cliente JavaScript líder para GraphQL. Impulsado por la comunidad, está diseñado para permitirle crear componentes de interfaz de usuario que interactúen con los datos GraphQL, ya sea al mostrar datos o al realizar mutaciones cuando ocurren ciertas acciones.

No es necesario cambiar todo en su aplicación para utilizar Apollo Client. Puede comenzar con una pequeña capa, una solicitud y expandir desde allí.

Sobre todo, Apollo Client está diseñado para ser simple, pequeño y flexible desde cero.

En esta publicación, detallaré el proceso de uso de Apollo Client dentro de una aplicación React.

Usaré elAPI GraphQL de GitHubcomo servidor.

Inicie una aplicación React

yo suelocreate-react-apppara configurar la aplicación React, que es muy conveniente y solo agrega lo básico de lo que necesitamos:

npx create-react-app myapp

npxes un comando disponible en la últimanpmversiones. Actualice npm si no tiene este comando.

e inicie el servidor local de la aplicación con npm:

npm start

Esto iniciará una aplicación enlocalhost:3000.

Ahora abiertosrc/index.js:

import React from 'react'
import ReactDOM from 'react-dom'
import './index.css'
import App from './App'
import registerServiceWorker from './registerServiceWorker'

ReactDOM.render(<App />, document.getElementById(‘root’)) registerServiceWorker()

y eliminar todo este contenido.

Empiece con Apollo Boost

Apollo Boost es la forma más fácil de comenzar a usar Apollo Client en un nuevo proyecto. Lo instalaremos además dereact-apolloygraphql.

En la consola, ejecuta

npm install apollo-boost react-apollo graphql

Crea un objeto ApolloClient

Empiece por importar ApolloClient desdeapollo-clientenindex.js:

import { ApolloClient } from 'apollo-client'

const client = new ApolloClient()

Por defecto, Apollo Client usa el/graphqlendpoint en el host actual, así que usemos unEnlace de Apolopara especificar los detalles de la conexión al servidor GraphQL configurando el URI del punto final de GraphQL.

Un Apollo Link está representado por unHttpLinkobjeto, del cual importamosapollo-link-http.

Apollo Link nos proporciona una forma de describir cómo queremos obtener el resultado de una operación GraphQL y qué queremos hacer con la respuesta.

En resumen, crea varias instancias de Apollo Link que actúan en una solicitud GraphQL una tras otra, proporcionando el resultado final que desea. Algunos enlaces pueden darle la opción de volver a intentar una solicitud si no tiene éxito, por lotes y mucho más.

Agregaremos un enlace Apollo a nuestra instancia del cliente Apollo para usar el URI del punto final GraphQL de GitHub.https://api.github.com/graphql

import { ApolloClient } from 'apollo-client'
import { createHttpLink } from 'apollo-link-http'

const client = new ApolloClient({ link: createHttpLink({ uri: https://api.github.com/graphql }) })

Almacenamiento en caché

Aún no hemos terminado. Antes de tener un ejemplo de trabajo también debemos decirApolloClientcualesestrategia de almacenamiento en cachéusar:InMemoryCachees el predeterminado y es bueno comenzar.

import { ApolloClient } from 'apollo-client'
import { createHttpLink } from 'apollo-link-http'
import { InMemoryCache } from 'apollo-cache-inmemory'

const client = new ApolloClient({ link: createHttpLink({ uri: https://api.github.com/graphql }), cache: new InMemoryCache() })

UsarApolloProvider

Ahora necesitamos conectar Apollo Client a nuestro árbol de componentes. Lo hacemos usandoApolloProvider, envolviendo nuestro componente de aplicación en el archivo principal de React:

import React from 'react'
import ReactDOM from 'react-dom'
import { ApolloClient } from 'apollo-client'
import { createHttpLink } from 'apollo-link-http'
import { InMemoryCache } from 'apollo-cache-inmemory'
import { ApolloProvider } from 'react-apollo'

import App from ‘./App’

const client = new ApolloClient({ link: createHttpLink({ uri: https://api.github.com/graphql }), cache: new InMemoryCache() })

ReactDOM.render( <ApolloProvider client={client}> <App /> </ApolloProvider>, document.getElementById(‘root’) )

Esto es suficiente para representar el valor predeterminado.create-react-apppantalla, con Apollo Client inicializado:

create-react-app running Apollo Client

losgqletiqueta de plantilla

Ahora estamos listos para hacer algo con Apollo Client, y vamos a buscar algunos datos de la API de GitHub y renderizarlos.

Para hacerlo, necesitamos importar elgqletiqueta de plantilla al comienzo deindex.js:

import gql from 'graphql-tag'

cualquier consulta GraphQL se creará utilizando esta etiqueta de plantilla, como esta:

const query = gql`
  query {
    ...
  }
`

Realizar una solicitud GraphQL

Importadorgqlfue el último elemento que necesitábamos en nuestro conjunto de herramientas.

Ahora estamos listos para hacer algo con Apollo Client, y vamos a buscar algunos datos de la API de GitHub y renderizarlos.

Obtenga un token de acceso para la API

Lo primero que debe hacer esobtener un token de acceso personaldesde GitHub.

GitHub lo facilita al proporcionar una interfaz desde la que puede seleccionar cualquier permiso que pueda necesitar:

GitHub interface to create a new personal access token

Por el bien de este tutorial de ejemplo, no necesita ninguno de esos permisos, están diseñados para acceder a datos de usuarios privados, pero solo consultaremos los datos de los repositorios públicos.

Sin embargo, todavía necesitas una ficha.

El token que obtienes es unToken de portador de OAuth 2.0.

Puede probarlo fácilmente ejecutándolo desde la línea de comando:

$ curl -H "Authorization: bearer ***_YOUR_TOKEN_HERE_***" -X POST -d " \
 { \
   \"query\": \"query { viewer { login }}\" \
 } \
" https://api.github.com/graphql

(reemplazar***_YOUR_TOKEN_HERE_***con el token real)

que debería darte el resultado

{"data":{"viewer":{"login":"***_YOUR_LOGIN_NAME_***"}}}

o

{
  "message": "Bad credentials",
  "documentation_url": "https://developer.github.com/v4"
}

si algo salió mal, por ejemplo, si olvidó insertar el token.

Ahora tenemos que enviar elAutorizaciónencabezado junto con nuestra solicitud GraphQL, al igual que hicimos en elcurlsolicitud anterior.

La forma de hacer esto con Apollo Client es mediante la creación de un middleware Apollo Link. Comience con la instalaciónapollo-link-context:

npm install apollo-link-context

Este paquete nos permite agregar un mecanismo de autenticación al establecer el contexto de nuestras solicitudes.

Podemos usarlo en este código haciendo referencia alsetContextfuncionar de esta manera:

import { setContext } from 'apollo-link-context'

const authLink = setContext((_, { headers }) => { const token = ‘*YOUR_TOKEN

return { headers: { …headers, authorization: Bearer </span><span style="color:#e6db74">${</span><span style="color:#a6e22e">token</span><span style="color:#e6db74">}</span><span style="color:#e6db74"> } } })

y una vez que tengamos este nuevo Apollo Link, podremoscomponereso con elHttpLinkque ya teníamos, usando elconcat()método en un enlace:

const link = authLink.concat(httpLink)

Aquí está el código completo parasrc/index.jsarchivo con el código que tenemos ahora:

import React from 'react'
import ReactDOM from 'react-dom'
import { ApolloClient } from 'apollo-client'
import { createHttpLink } from 'apollo-link-http'
import { InMemoryCache } from 'apollo-cache-inmemory'
import { ApolloProvider } from 'react-apollo'
import { setContext } from 'apollo-link-context'
import gql from 'graphql-tag'

import App from ‘./App’

const httpLink = createHttpLink({ uri: https://api.github.com/graphql })

const authLink = setContext((_, { headers }) => { const token = ‘*YOUR_TOKEN

return { headers: { …headers, authorization: Bearer </span><span style="color:#e6db74">${</span><span style="color:#a6e22e">token</span><span style="color:#e6db74">}</span><span style="color:#e6db74"> } } })

const link = authLink.concat(httpLink)

const client = new ApolloClient({ link: link, cache: new InMemoryCache() })

ReactDOM.render( <ApolloProvider client={client}> <App /> </ApolloProvider>, document.getElementById(‘root’) )

ADVERTENCIA ⚠️ 🚧 Tenga en cuenta que este código es unejemplocon fines educativos y expone su token de API GraphQL de GitHub al mundo para que lo vea en su código de interfaz. El código de producción debe mantener este token privado en el backend.

Ahora podemos hacer la primera solicitud GraphQL en la parte inferior de este archivo, y esta consulta de muestra solicita los nombres y los propietarios de los 10 repositorios más populares, con más de 50k estrellas:

const POPULAR_REPOSITORIES_LIST = gql`
{
  search(query: "stars:>50000", type: REPOSITORY, first: 10) {
    repositoryCount
    edges {
      node {
        ... on Repository {
          name
          owner {
            login
          }
          stargazers {
            totalCount
          }
        }
      }
    }
  }
}
`

client.query({ query: POPULAR_REPOSITORIES_LIST }).then(console.log)

Ejecutar este código con éxito devuelve el resultado de nuestra consulta en la consola del navegador:

console log of executed query

Renderizar un conjunto de resultados de consulta GraphQL en un componente

Lo que vimos hasta ahora ya es genial. Lo que es aún mejor es usar el conjunto de resultados de graphql para renderizar sus componentes.

Dejamos que Apollo Client se encargue de la carga (o la alegría) de obtener los datos y manejar todas las cosas de bajo nivel, y podemos concentrarnos en mostrar los datos, utilizando elgraphqlpotenciador de componentes ofrecido porreact-apollo.

Agregue esto en elApp.jsexpediente:

import React from 'react'
import { graphql } from 'react-apollo'
import { gql } from 'apollo-boost'

const POPULAR_REPOSITORIES_LIST = gql </span><span style="color:#e6db74">{ </span><span style="color:#e6db74"> search(query: "stars:&gt;50000", type: REPOSITORY, first: 10) { </span><span style="color:#e6db74"> repositoryCount </span><span style="color:#e6db74"> edges { </span><span style="color:#e6db74"> node { </span><span style="color:#e6db74"> ... on Repository { </span><span style="color:#e6db74"> name </span><span style="color:#e6db74"> owner { </span><span style="color:#e6db74"> login </span><span style="color:#e6db74"> } </span><span style="color:#e6db74"> stargazers { </span><span style="color:#e6db74"> totalCount </span><span style="color:#e6db74"> } </span><span style="color:#e6db74"> } </span><span style="color:#e6db74"> } </span><span style="color:#e6db74"> } </span><span style="color:#e6db74"> } </span><span style="color:#e6db74">} </span><span style="color:#e6db74">

const App = graphql(POPULAR_REPOSITORIES_LIST)(props => <ul> {props.data.loading ? ‘’ : props.data.search.edges.map((row, i) => <li key={row.node.owner.login + ‘-’ + row.node.name}> {row.node.owner.login} / {row.node.name}: {’ '} <strong> {row.node.stargazers.totalCount} </strong> </li> )} </ul> )

export default App

Aquí está el resultado de nuestra consulta renderizada en el componente 😀

The result of our query rendered in the component


Servidor Apollo

Un servidor GraphQL tiene la función de aceptar solicitudes entrantes en un punto final, interpretar la solicitud y buscar cualquier dato que sea necesario para satisfacer las necesidades del cliente.

Hay toneladas de diferentes implementaciones de servidores GraphQL para todos los lenguajes posibles.

Apollo Server es una implementación de servidor GraphQL para JavaScript, en particular para elNode.jsplataforma.

Es compatible con muchos marcos populares de Node.js, que incluyen:

Apollo Server nos da básicamente 3 cosas:

  • nos da una forma de describir nuestros datos con unesquema.
  • proporciona el marco pararesolutores, que son funciones que escribimos para obtener los datos necesarios para cumplir con una solicitud.
  • facilita el manejoautenticaciónpara nuestra API.

Para comenzar, cree una carpeta llamadaappserver, entra y correnpm init --yespara inicializar unpackage.jsonexpediente.

Entonces correnpm install apollo-server graphql.

Patio de recreo Apollo

Si prefiere un área de juegos en línea, hay 2 increíbles áreas de juegos para Apollo que recomiendo.

El primero está alojado enFalla, el segundo enCódigo Caja de arena.

Vaya y mezcle / bifurque esos proyectos iniciales para crear su propio Apollo Server.

Apollo Server Hola mundo

Crear unindex.jsexpediente.

Primero importasApolloServerygqldesdeapollo-server:

const { ApolloServer, gql } = require('apollo-server');

Creamos una definición de esquema usando elgqletiqueta. Una definición de esquema es una cadena literal de plantilla que contiene la descripción de nuestra consulta y los tipos asociados con cada campo:

const typeDefs = gql`
  type Query {
    hello: String
  }
`

Aresolveres un objeto que asigna campos en el esquema a funciones de resolución, capaz de buscar datos para responder a una consulta.

Aquí hay un solucionador simple que contiene la función de resolución para elhellocampo, que devuelve elHello world!cuerda:

const resolvers = {
  Query: {
    hello: (root, args, context) => {
      return 'Hello world!'
    }
  }
}

Dados esos 2 elementos, la definición del esquema y el resolutor, inicializamos un nuevo objeto ApolloServer:

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

Luego llamamos al método listen () en el objeto del servidor, y escuchamos la promesa de resolver, lo que indica que el servidor está listo:

server.listen().then(({ url }) => {
  console.log(`🚀 Server ready at ${url}`)
})

Aquí está el código completo para el ejemplo simple de Hello World:

const { ApolloServer, gql } = require('apollo-server');

// Construct a schema, using GraphQL schema language const typeDefs = gql </span><span style="color:#e6db74"> type Query { </span><span style="color:#e6db74"> hello: String </span><span style="color:#e6db74"> } </span><span style="color:#e6db74">

// Provide resolver functions for your schema fields const resolvers = { Query: { hello: (root, args, context) => { return ‘Hello world!’ } } }

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

server.listen().then(({ url }) => { console.log(🚀 Server ready at </span><span style="color:#e6db74">${</span><span style="color:#a6e22e">url</span><span style="color:#e6db74">}</span><span style="color:#e6db74">) })

Ahora correnode index.jsy desde otra ventana de la consola ejecuta:

$ curl \
  -X POST \
  -H "Content-Type: application/json" \
  --data '{ "query": "{ hello }" }' \
  http://localhost:4000/graphql

Esto debería devolverle los datos:

{
  "data": {
    "hello": "Hello world!"
  }
}

Puede hacer que su cliente interactúe con esto usando este simple ejemplo de archivo App.js, que puede ingresar desde el ejemplo de API de GitHub anterior:

import React from 'react'
import { gql } from 'apollo-boost'
import { Query } from 'react-apollo'

const App = () => ( <Query query={gql</span><span style="color:#e6db74"> { </span><span style="color:#e6db74"> hello </span><span style="color:#e6db74"> } </span><span style="color:#e6db74"> } > {({ loading, error, data }) => { if (loading) return <p>Loading</p> if (error) return <p>Error :(</p>

  <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">data</span>.<span style="color:#a6e22e">hello</span>
}}

</Query> )

export default App

Tienes que cambiar elhttpLinkuri en elindex.jsarchivar a:

const httpLink = createHttpLink({ uri: 'http://localhost:4000/graphql' })

Más tutoriales de graphql: