Do you want to switch to Platzi in English?
25

Introducción a GraphQL

20649Puntos

hace 1 a

Curso de GraphQL
Curso de GraphQL

Curso de GraphQL

Con GraphQL puedes hacer una sola consulta para obtener los datos que necesitas para tu aplicación. Aprende a implementar la solución desarrollada por Facebook para manejar tus datos de manera sencilla en el backend y en el frontend.

GraphQL es un lenguaje de queries que te permite definir qué datos pedirle a un API. Se trata de una tecnología que Facebook empezó a desarrollar en 2012, aunque fue anunciada en 2015.

Lo interesante de GraphQL

Con GraphQL el cliente (el Frontend) decide qué datos pedir al servidor y de qué forma le conviene recibirlos, lo que quiere decir que, si llegara a necesitar información adicional, o si simplemente deja de necesitar un dato, no tiene que modificar el backend: basta con cambiar la query de GQL en el cliente ¡y listo!

Lo importante de GraphQL

GraphQL no es una librería o framework: es una especificación de cómo implementarlo en cualquier lenguaje. Además existen implementaciones ya creadas en lenguajes como JavaScript, Ruby, Python, Scala, Java, Clojure, Go, PHP, .NET, etc. También existen clientes para consumir un API GraphQL desde JS, iOS, Android, React, Angular, entre otras.

La interacción con GraphQL

Cuando tenemos un API Rest, la forma de interactuar con ella empieza con una petición HTTP que hacemos usando alguno de los métodos, GET, POST, PUT o DELETE, a ciertas URL únicas por recurso del API.

Por ejemplo, si hacemos una petición GET /api/careers/, esto nos devuelve la lista de carreras. Si le agregamos /:id, podemos pedir los datos de una carrera específica. Así también con POST podemos crear nuevas carreras, con PUT y DELETE nos sirve para actualizar y borrar carreras.

En cambio con GQL tenemos un solo endpoint, normalmente /graphql, y solo interactuamos con el mediante el método POST. Para decirle que datos queremos obtener, crear o modificar colocamos en el cuerpo de la petición alguna de estas tres cosas:

  • Query
  • Mutation
  • Subscription

Estas son las 3 formas de interactuar con un API GraphQL. Ahora vamos a ver de qué se trata cada una.

Query

El primer concepto importante de GQL es la Query. Una query es una consulta que hacemos a nuestra API:

query {
	getCourse("id": 1) {
		id
		title
		url
		concepts {
			title
			materials {
				title
				url
			}
		}
	}
}

Ese es un ejemplo de una query para pedir una lista de carreras. De cada carrera podemos pedir el id, el title, el badge, si está approved y sus cursos. También podemos pedir los mismos datos de la carrera para cada curso, más la URL. En ese caso, este es el contenido de la respuesta de dicha query:

{
	"data": {
		"getCourse": {
			"id": 1,
			"title": "Fundamentos de JavaScript",
			"url": "https://platzi.com/clases/fundamentos-javascript/",
			"concepts": [
				...
			]
		}
	}
}

Como vemos, lo que se obtiene es un objeto con nuestros datos. Adentro se encuentra el curso que pedimos al servidor, solamente con las propiedades que solicitamos. De esta forma, es nuestro cliente quien define los datos que necesita. El servidor simplemente se encarga de responder con esos datos específicamente.

Es cierto que un curso, un concepto y un material pueden tener muchos más datos, pero estos son los únicos que nosotros necesitamos. A diferencia de un API Restful, GQL nos devuelve exactamente lo que necesitamos para nuestra UI: ni más ni menos.

Mutation

Las queries nos permiten obtener datos, pero toda aplicación necesita una forma de crear, modificar, eliminar o interactuar con estos datos. Estas acciones son llamadas mutaciones. Una mutación es similar a una función: recibe ciertos parámetros, realiza un cambio y devuelve una respuesta. Así:

mutation {
	addToLearningPath(
		"id": 1
	) {
		title
		badge
		approved
		url
	}
}

En este caso, esa mutación le indica al servidor que queremos agregar el curso con el ID 1 a nuestro plan de estudios. Entonces le decimos que nos devuelva como respuesta: el título, el badge, la aprobación y la URL. La respuesta sería algo así:

{
	"data": {
		"addToLearningPath": {
			"title": "Fundamentos de JavaScript",
			"badge": "https://static.platzi.com/media/achievements/badge-Fundamentos-js.png",
			"approved": false,
			"url": "https://platzi.com/clases/fundamentos-javascript/"
		}
	}
}

Aquí hemos visto que la respuesta nos entrega únicamente los datos que pedimos del curso que agregamos al plan de estudios. Luego, con esos datos podemos agregar nuestro curso a la UI de un plan de estudios.

Subscription

Otra opción importante de GQL es la suscripción. Esto no está implementado por todas las librerías para backend, ya que hace poco se volvió parte oficial de la especificación. Lo que nos permiten las suscripciones es, como su nombre dice, suscribirnos a cambios que ocurran en el servidor.

Por ejemplo: es posible suscribirnos a nuevas notificaciones para enterarnos en tiempo real de lo que ocurre con nuestra aplicación. Se trata, básicamente, de mantener una conexión por WebSockets. Veamos un ejemplo:

subscription {
	notificationOf("type": "answer") {
		id
		type
		data {
			discussion {
				id
				title
			}
			answer {
				author {
					avatar
					username
				}
				date
			}
		}
	}
}

Con esta suscripción podemos enterarnos, por ejemplo, de cuándo nos responden una pregunta. De cada notificación vamos a obtener el ID, el tipo (siempre answer gracias al filtro) y otros datos específicos como el ID, título de la pregunta, el autor (con su nombre y avatar) y la fecha de la respuesta.

Al llegar una notificación recibiremos un objeto similar a este:

{
	"data": {
		"id": 123,
		"type": "answer",
		"data": {
			"discussion": {
				"id": 456,
				"title": "¿Cómo funciona GraphQL?"
			},
			"answer": {
				"author": {
					"avatar": "<url>",
					"username": "sergiodxa"
				},
				"date": "2017-05-28T23:48:27.752Z"
			}
		}
	}
}

Schema

Cuando desarrollamos un APIGQL debemos definir nuestros esquemas (schemas) de datos. Un esquema en GQL puede ser la definición de un tipo de dato, o la definición de las formas de obtener e interactuar con ellos. Por ejemplo, podríamos definir un esquema similar a este:

type Course {
	id: Int!
	title: String!
	badge: String!
	approved: Boolean
	url: String!
	description: String
	concepts: [Concept]
}

Aquí estamos definiendo que en nuestra aplicación existe un objeto de tipo Course que tiene los siguientes datos:

  • id un número, obligatorio
  • title un string, obligatorio
  • badge un string, obligatorio
  • approved un booleano, opcional
  • url un string, obligatorio
  • description un string, opcional
  • concepts una lista de objetos de tipo Concept, opcional

La propiedad concepts es básicamente una relación que indica que un curso tiene varios conceptos. Luego, necesitamos definir las posibles formas de obtener este curso.

type Query {
	getCourse(id: Int!): Courses
	getCourses(): [Courses]
}

Esto nos permite ejecutar una query llamada getCourse pasándole un id, obtener un único curso o ejecutar getCourses para obtener una lista de todos los cursos. Similar a la query que vimos antes. Después necesitamos definir las posibles mutaciones: las formas de interactuar con nuestra API:

type Mutation {
	addToLearningPath(id: String!): Course
	createCourse(
		title: String!
		badge: String!
		url: String
		description: String
	): Course
	updateCourse(
		title: String
		badge: String
		url: String
		description: String
	): Course
}

Estas mutaciones que definimos en nuestro esquema son las formas de interactuar con nuestros cursos. Podemos agregarlos a nuestro plan de estudios, crear o modificar cursos. También hay que decidir a qué datos podemos suscribirnos:

type Subscription {
	notificationOf(type: String!): Notification
}

Para definir las suscripciones simplemente indicamos el nombre, los parámetros que quiero recibir y lo que espero que devuelva. Igualmente con las mutaciones. Por último, es necesario estructurar nuestro esquema final, que siempre es algo así:

type Schema {
	query: Query
	mutation: Mutation
	subscription: Subscription
}

En este punto se trata simplemente indicar que nuestro esquema tiene query, mutation y subscription, y que cada uno corresponde con lo que definimos antes.

Resolvers

Los esquemas por sí solos no hacen nada: únicamente definen qué se puede hacer en nuestra APIa través de los resolvers, que son funciones que se encargan de procesar cada posible query, mutación o suscripción de nuestra API y de responder con los datos necesarios, según la definición de nuestro esquema. Por ejemplo:

const getCourse = async id => Course.findById(id)

Esta función de una línea se encarga obtener un curso mediante el ID usando el modelo Course de nuestra base de datos. En este caso, estamos pidiendo todos los posibles campos de nuestra tabla “curso” de la base de datos. Pero también es posible (y de hecho es la idea de GQL) pedir a nuestra BD únicamente los datos que indicó el cliente. Así se optimiza la lectura y escritura de la BD.

GraphiQL

GraphQL tiene su propio IDE, creado por Facebook, llamado GraphiQL (pronunciado grafical). Este IDE funciona mediante web, mostrándose, normalmente, en la URL de nuestro API cuando entramos desde un navegador. Este se conecta con nuestros esquemas de datos para mostrarnos documentación del API y nos deja probarlo, dando sugerencias de autocomplete y mostrándonos las respuestas a las distintas peticiones, mutaciones y suscripciones.

GraphiQL

Aquí hemos visto un ejemplo de cómo se ve GraphiQL. En la esquina superior izquierda se encuentra nuestra petición; en la parte inferior tenemos variables y a la derecha se muestran los resultados de correr esa petición.

GraphQL vs Restful

Un problema común de los API Rest es que requieren muchas peticiones para obtener todos los datos necesarios en una vista de la aplicación. Estos nos permiten hacer dichas peticiones -con lo que podemos estar consumiendo datos de nuestros usuarios y tardar mucho en obtener todas las respuestas-, o crear URLs personalizadas para responder con todos los datos necesarios, -en cuyo caso estaríamos creando endpoints en nuestro API que nunca más se van a volver a usar dado su alto nivel de personalización-.

La buena noticia es que ambos problemas son resueltos por GraphQL, permitiendo que el cliente decida qué datos quiere en cada momento y que pueda manejar todas las peticiones con una sola URL. Así, en vez de crear URLs personalizadas, simplemente definimos los posibles datos de nuestro API y la forma de interactuar con él… el resto se lo dejamos al frontend.

Palabras finales

Rest no está muerto. Todavía puede ser útil para la comunicación entre servicios de backend, pero para un API, de cara al cliente que use web, mobile, desktop, GraphQL tiene muchas ventajas. Gracias a clientes como Apollo o Relay Modern es muy fácil empezar a usarlo en cualquier tipo de aplicación frontend.

Si quieres aprender más sobre este lenguaje de queries, entra ya al Curso de GraphQL.

Curso de GraphQL
Curso de GraphQL

Curso de GraphQL

Con GraphQL puedes hacer una sola consulta para obtener los datos que necesitas para tu aplicación. Aprende a implementar la solución desarrollada por Facebook para manejar tus datos de manera sencilla en el backend y en el frontend.
Sergio Daniel
Sergio Daniel
@sergiodxa

20649Puntos

hace 1 a

Todas sus entradas
Escribe tu comentario
+ 2
Ordenar por:
3
111474Puntos

Excelente introducción de GraphQL, muy interesante solución para generar API’s dinámicas sin tener una gran cantidad de endpoints y documentar que data entrega cada uno de ellos.

1
277Puntos

Qué base de datos puedo usar para implememtar GraphQL en mi Frontend, Mysql, RethinkDb, etc? O GraphQL también es un motor para guardar datos?

2
20649Puntos
1 a

GraphQL no se implemente en el frontend, es en el backend.

Se puede usar la base de datos que quieras, de hecho GrahpQL no tiene por que pegarle a una base de datos, podés usar GraphQL como un intermediario de un API Rest, o de otro API GraphQL, o combinar todo y que un mismo API consuma datos desde varias bases de datos, desde Rest, desde otro GraphQL, archivos en disco, lo que quieras.

0
4414Puntos
8 meses

Sergio una duda, al comienzo del post dices que:

Lo más interesante es que con GraphQL es el cliente, el Frontend, el que decide qué datos pedir y de qué forma al servidor…

Pero ahora mencionas que GraphQL se implementa en el backend.

Me queda la duda de si GraphQL tiene una capa en ambos lados, es decir tanto back como front?

Saludos y gran artículo.

0
984Puntos
8 meses

Carlos,
A lo que Sergio se refería es que en un escenario Rest habitual el Frontend tenía un listado de recursos que consumir (bajo los definidos verbos HTTP que todos conocemos), solo podía enviar parámetros a esos endpoints y el servidor le devolvía un Rest con tooooda la información solicitada y la no solicitada también:

Por ejemplo: Si solo necesitas el nombre y la fecha de nacimiento de un usuario, un escenario Rest posiblemente te devuelva más que eso (osea, email, dirección, pais, etc).

LA RESPUESTA a tu pregunta
En GraphQL el escenario cambia, es el FrontEnd el que envía al Backend los atributos que necesita (Obviamente debe existir una configuración previa en el backend), por ejemplo, si solo necesita el nombre y la fecha de nacimineto de un usuario, eso es precisamente lo que pide y eso es lo que GraphQL le devuelve.

Espero haber aportado.

Saludos,

1
2586Puntos

Yo llevo usando API rest desde mis inicios como desarrollador (desde el año pasado) y estoy trabajando con un framework de NodeJs llamado Loopback, en conjunto con AngularJs para el frontend. Hago este comentario porque Loopback, en sus endPoints puede aceptar ciertos parametros para modelar los datos de entrada, y se les llaman filtros.

Es bastante mas complicado que el GraphQL pero un ejemplo seria:

GET /products
con filtros como:

{
	where: {
		state: 'active'//Cumplan la condicion
	},
	order: 'name ASC', // Ordenar por nombre
	limit: 5, //Solo 5 elementos
	skip: 5//Saltar los primeros 5
}

Desde angular se pueden manipular completamente estos filtros con un SDK, sin angular, se pueden colocar dichos filtros directamente en la url

Puede que sea una aproximacion a lo que hace GraphQL, pero es indiscutible que Graph es mucho mas descriptivo 😄

3
20649Puntos
1 a

El problema es que esos son hacks para evitar problemas con Rest, al final terminas armando un híbrido entre Rest y GrahpQL pero sin ser 100% GraphQL, para eso mejor usar GQL 😃

1
2168Puntos

Muy buen material Sergio, muchas gracias!

0

Excelente. ahora mismo estoy planeando los schemas para n nuevo proyecto.

0
103Puntos

Hola Sergio.
Nos puedes indicar por favor el grado de complejidad de GraphQL, el tiempo de duración del curso que impartes. Como aplicas GQL a Laravel? Si tienes un nuevo proyecto en laravel puedo generar todo con GQL?
¿Porque el plan mensual no permite Paypal? (?)

Gracias
Quito.- Ecuador

1
20649Puntos
1 a
  1. Depende ¿Cómo medís la complejidad vos y que te parece complejo? La verdad no es tán difícil de aprender, con lo que hay arriba aprendiste un montón, luego es implementarlo (que depende del lenguaje y librería/framework).
  2. Yo no imparto el curso de GraphQL.
  3. No uso PHP, pero se que hay librerías de PHP y Laravel para GraphQL
  4. Sí podrías hacer tu API con GQL desde el principio.
  5. No trabajo en Platzi, pregunta a [email protected] por eso.
0
5008Puntos

relay modern o apollo?

2
20649Puntos
1 a

Apollo FTW, tiene SSR, es muy simple, funciona con React, Angular, Android y iOS y te da herramientas para hacer servidores de GraphQL más fácil.

0

Solo para aclarar conceptos.
las Apis, tienen dos caras por decirlo así, el servidor como una capa de datos, y el cliente que cosumira la api, que en teoria también estará en el servidor. Gaphql tiene la misma “estructura” ??. Perdón si no me hago entender.

0

Sergio excelente articulo, que api me recomiendas para empezar y que servidor de aplicacion recomiemdas: jboss o tomcat. Yo trabajo con oracle y queremos migrar nuestras app de que estan en OracleForm a web, GraphL seria una buena opción? Te comento que la parte de logica la tenemos bien mapeada en oracle a través de procedimientos y funciones. Gracias.

1
20649Puntos
1 a

Nunca trabajé con tecnologías Oracle o Java así que no sabría decirte.

0
236Puntos

Excelente artículo!! Intetare usar GrahpQL en futuros proyectos ya que reduciría el tiempo de trabajo en realizar los diferentes endpoints en un API RestFul.

0
25Puntos

el uso de GQL implica que todos proceso de cálculos se realiza en el cliente?

1
20649Puntos
1 a

No necesariamente, cuando realizas una mutación o una query podés hacer lo que quieras.