Introducció
L'optimització de consultes en GraphQL és crucial per assegurar que les aplicacions siguin eficients i ràpides. A mesura que les aplicacions creixen, les consultes poden esdevenir més complexes i, si no es gestionen adequadament, poden afectar el rendiment del sistema. En aquesta secció, explorarem diverses tècniques per optimitzar les consultes de GraphQL.
Conceptes clau
- Reducció de la profunditat de la consulta: Limitar la profunditat de les consultes per evitar que els usuaris puguin fer consultes massa profundes que puguin afectar el rendiment.
- Limitació del nombre de nodes: Controlar el nombre de nodes retornats per una consulta per evitar sobrecàrregues.
- Batching i caching: Utilitzar tècniques d'agrupació i emmagatzematge en memòria cau per millorar l'eficiència de les consultes.
- DataLoader: Una eina per gestionar l'agrupació i la memòria cau de les consultes.
- Persisted Queries: Utilitzar consultes persistents per millorar el rendiment i la seguretat.
Reducció de la profunditat de la consulta
Explicació
Limitar la profunditat de les consultes és una tècnica per evitar que els usuaris puguin fer consultes massa profundes que puguin afectar el rendiment del servidor. Això es pot aconseguir establint un límit màxim de profunditat per a les consultes.
Exemple
const { createComplexityLimitRule } = require('graphql-validation-complexity'); const complexityLimitRule = createComplexityLimitRule(1000, { onCost: (cost) => console.log('Query cost:', cost), formatErrorMessage: (cost) => `Query with cost ${cost} exceeds complexity limit`, }); const server = new ApolloServer({ schema, validationRules: [complexityLimitRule], });
Explicació del codi
- createComplexityLimitRule: Crea una regla de validació per limitar la complexitat de les consultes.
- complexityLimitRule: Defineix la regla amb un límit de complexitat de 1000.
- validationRules: Aplica la regla de validació al servidor Apollo.
Limitació del nombre de nodes
Explicació
Controlar el nombre de nodes retornats per una consulta és una altra tècnica per evitar sobrecàrregues. Això es pot fer establint límits en el nombre de resultats retornats per les consultes.
Exemple
Explicació del codi
- first: 10: Limita el nombre de nodes retornats a 10.
Batching i caching
Explicació
L'agrupació (batching) i l'emmagatzematge en memòria cau (caching) són tècniques per millorar l'eficiència de les consultes. L'agrupació permet combinar múltiples consultes en una sola, mentre que l'emmagatzematge en memòria cau permet reutilitzar els resultats de consultes anteriors.
Exemple amb DataLoader
const DataLoader = require('dataloader'); const userLoader = new DataLoader(keys => batchGetUsers(keys)); function batchGetUsers(keys) { return User.find({ _id: { $in: keys } }); } // Utilització en un resolver const resolvers = { Query: { user: (parent, args, context) => { return context.userLoader.load(args.id); }, }, };
Explicació del codi
- DataLoader: Una eina per gestionar l'agrupació i la memòria cau de les consultes.
- batchGetUsers: Una funció que agrupa les consultes per obtenir usuaris.
- context.userLoader.load: Utilitza el DataLoader per carregar l'usuari amb l'ID especificat.
Persisted Queries
Explicació
Les consultes persistents són consultes predefinides que es guarden al servidor. Això permet millorar el rendiment i la seguretat, ja que les consultes no es poden modificar en temps d'execució.
Exemple
const { ApolloServer, gql } = require('apollo-server'); const { createPersistedQueryLink } = require('apollo-link-persisted-queries'); const { HttpLink } = require('apollo-link-http'); const fetch = require('node-fetch'); const link = createPersistedQueryLink().concat( new HttpLink({ uri: '/graphql', fetch }) ); const server = new ApolloServer({ typeDefs, resolvers, persistedQueries: { cache: new Map(), }, });
Explicació del codi
- createPersistedQueryLink: Crea un enllaç per a les consultes persistents.
- persistedQueries.cache: Utilitza una memòria cau per emmagatzemar les consultes persistents.
Exercicis pràctics
Exercici 1: Limitar la profunditat de les consultes
- Configura una regla de validació per limitar la profunditat de les consultes a 5.
- Prova una consulta que superi aquest límit i observa el resultat.
Solució
const { depthLimit } = require('graphql-depth-limit'); const server = new ApolloServer({ schema, validationRules: [depthLimit(5)], });
Exercici 2: Utilitzar DataLoader per a l'agrupació
- Crea un DataLoader per carregar usuaris en lots.
- Utilitza el DataLoader en un resolver per carregar un usuari per ID.
Solució
const DataLoader = require('dataloader'); const userLoader = new DataLoader(keys => batchGetUsers(keys)); function batchGetUsers(keys) { return User.find({ _id: { $in: keys } }); } const resolvers = { Query: { user: (parent, args, context) => { return context.userLoader.load(args.id); }, }, };
Conclusió
L'optimització de consultes en GraphQL és essencial per assegurar que les aplicacions siguin eficients i ràpides. Mitjançant tècniques com la reducció de la profunditat de les consultes, la limitació del nombre de nodes, l'agrupació i l'emmagatzematge en memòria cau, i l'ús de consultes persistents, podem millorar significativament el rendiment de les nostres aplicacions. Practicar aquestes tècniques amb exercicis pràctics ajudarà a consolidar els coneixements adquirits.
Curs de GraphQL
Mòdul 1: Introducció a GraphQL
- Què és GraphQL?
- GraphQL vs REST
- Configuració d'un servidor GraphQL
- Conceptes bàsics de l'esquema de GraphQL
Mòdul 2: Conceptes bàsics
Mòdul 3: Disseny avançat d'esquemes
Mòdul 4: Treballant amb dades
- Connexió a una base de dades
- Estratègies de recuperació de dades
- Agrupació i emmagatzematge en memòria cau
- Gestió d'errors
Mòdul 5: Rendiment i seguretat
Mòdul 6: Eines i ecosistema
Mòdul 7: Proves i desplegament
- Proves unitàries de resolvers
- Proves d'integració
- Integració contínua
- Desplegament de servidors GraphQL