GraphQL vs REST: los mismos datos pedidos de las dos formas | We.Inc
Compara GraphQL y REST con los mismos datos pedidos de las dos formas: número de peticiones, over-fetching, caché, cómo llegan los errores y una tabla para elegir.
REST expone muchas URL, una por recurso, y el servidor decide qué contiene cada respuesta. GraphQL expone un único endpoint, normalmente /graphql, al que el cliente envía una consulta que nombra exactamente los campos que quiere. REST obtiene caché HTTP gratis por URL; GraphQL ahorra viajes de ida y vuelta y recorta los campos que no se usan, a cambio de más trabajo en el servidor.
De un vistazo
Tema
REST
GraphQL
Endpoints
Una URL por recurso
Un endpoint, a menudo /graphql
Quién elige los campos
El servidor
El cliente, en la consulta
Datos relacionados
A menudo varias peticiones
Anidados en una sola consulta
Caché HTTP
Integrada para GET por URL
Requiere consultas GET, persisted queries o una caché en el cliente
Errores
Sobre todo códigos de estado HTTP
Un array errors, a menudo junto a datos parciales
Esquema
Opcional (OpenAPI)
Obligatorio y tipado
La comparación de abajo pide la misma pantalla de datos de las dos formas. Elige un escenario para ver las llamadas REST que haría un cliente junto a la única consulta GraphQL que las sustituye, y lo que cada respuesta omite o añade.
Elige un escenario, como una página de perfil con publicaciones recientes.
Lee las peticiones REST a la izquierda y la consulta GraphQL a la derecha.
Compara el número de peticiones que aparece bajo los paneles.
Lee la nota para ver dónde cada estilo envía más datos de los que necesita la pantalla.
No pases una API REST que funciona a GraphQL solo por moda. La ventaja aparece cuando muchas pantallas distintas necesitan porciones distintas de datos relacionados.
Expón un campo id estable en cada tipo de GraphQL para que las librerías de cliente puedan normalizar su caché con él.
Revisa el array errors en cada respuesta de GraphQL, aunque el estado sea 200 y haya datos.
Pon límites de profundidad y de coste en un endpoint GraphQL público, porque una sola consulta anidada puede pedir muchísimo trabajo.
Preguntas frecuentes
¿GraphQL es más rápido que REST?
No por sí solo. Puede reducir los viajes de ida y vuelta y el tamaño de la respuesta en pantallas que necesitan datos relacionados, pero cada consulta puede costarle más al servidor. Un endpoint REST bien diseñado para una pantalla puede ser igual de rápido.
¿Por qué un error de GraphQL llega con estado 200?
Un campo puede fallar mientras otros funcionan, así que el servidor devuelve los datos que tiene más un array errors. La guía de GraphQL sobre HTTP usa 2xx para el éxito parcial; los servidores que responden con application/graphql-response+json usan 400 cuando una petición no pasa la validación.
¿Una CDN puede cachear respuestas de GraphQL?
Sí, si las consultas se envían con GET, que los servidores pueden permitir solo para consultas. Las consultas largas pueden superar los límites de la URL, así que los equipos usan persisted queries que envían un hash corto en lugar del documento entero.
¿Puedo usar los dos en un mismo producto?
Muchos equipos lo hacen. Las subidas de archivos, los webhooks y los recursos públicos sencillos suelen quedarse como rutas REST, mientras las pantallas de la app leen a través de una capa GraphQL que puede llamar por debajo a esos mismos servicios.
¿GraphQL necesita su propia base de datos?
No. Un servidor GraphQL es una capa de resolvers, pequeñas funciones que obtienen cada campo de donde estén los datos: una base de datos, un servicio REST o un archivo. El esquema describe formas, no almacenamiento.
Over-fetching y under-fetching
Un endpoint REST devuelve una forma fija. Una pantalla de lista que solo muestra nombres sigue descargando todos los campos de cada usuario, y eso es over-fetching. Una pantalla de detalle que necesita un usuario más sus publicaciones más el número de comentarios de cada una puede requerir varias llamadas, y eso es under-fetching.
GraphQL traslada esa decisión al cliente. La consulta enumera los campos y el servidor devuelve esa forma y nada más. El precio es que el servidor debe soportar cualquier combinación de campos que un cliente pueda pedir.
La caché funciona de otra manera
Con REST, una URL es una clave de caché. Los navegadores y las CDN pueden guardar una respuesta GET y reutilizarla, porque GET y HEAD son los métodos cacheables. La mayor parte del tráfico GraphQL es POST a una sola URL, que esas cachés no guardan.
Los clientes GraphQL lo compensan en la app: dividen las respuestas en objetos y los guardan por id, de modo que dos consultas que tocan el mismo usuario comparten un solo registro en caché. graphql.org recomienda un campo id único global precisamente por eso.
Errores y códigos de estado
REST se apoya en la línea de estado: 404 para un registro que no existe, 401 cuando no hay sesión iniciada, 422 para una entrada no válida. Los clientes pueden decidir solo con el código.
Una respuesta GraphQL tiene una clave data, una clave errors o ambas. Un problema de sintaxis o de validación da errors y nada de data. Un fallo dentro de un campo da datos parciales en los que ese campo es null, y una entrada de error cuyo path apunta a él.
Cuál elegir
Tabla de decisión
Tu situación
Se inclina hacia
API pública que terceros llaman con curl
REST
Muchas pantallas, cada una con distintos datos relacionados
GraphQL
Mucha caché en CDN del tráfico de lectura
REST, o GraphQL con persisted queries por GET
Clientes móviles en redes lentas
GraphQL, menos viajes de ida y vuelta
CRUD sencillo sobre unas pocas tablas
REST
Varios servicios de backend tras una única puerta de entrada
GraphQL como capa de gateway
Qué viaja por la red
Una petición GraphQL con fetch
Cada operación es un POST de JSON con las claves query y variables al único endpoint. La cabecera Accept pide el tipo de respuesta GraphQL más reciente, con JSON normal como alternativa.
Una respuesta GraphQL parcial
Un campo falló, así que es null y la entrada de errors lo nombra con path. El resto de los datos llegó igualmente.
Perfil con publicaciones
REST necesita una segunda llamada para las publicaciones, y ambas respuestas llevan todos los campos que incluye el servidor. La consulta GraphQL devuelve solo el nombre, el avatar y tres títulos de publicaciones.
Solo nombres
Para una lista sencilla, la llamada REST es una sola petición en cualquier caso, pero envía registros de usuario completos. GraphQL envía solo los dos campos pedidos.
Publicación con comentarios y autores
Sin un endpoint a medida, REST recorre el árbol un nivel por petición, y obtener el autor de cada comentario puede suponer una llamada más por comentario. GraphQL anida el árbol entero en una sola consulta.
Crear una publicación
Las escrituras se parecen: una petición cada una. REST usa el método POST sobre una URL de colección; GraphQL envía una mutation, también como POST de HTTP, y elige qué campos de la nueva publicación devolver.