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

  1. 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.
  2. Limitació del nombre de nodes: Controlar el nombre de nodes retornats per una consulta per evitar sobrecàrregues.
  3. Batching i caching: Utilitzar tècniques d'agrupació i emmagatzematge en memòria cau per millorar l'eficiència de les consultes.
  4. DataLoader: Una eina per gestionar l'agrupació i la memòria cau de les consultes.
  5. 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

query {
  users(first: 10) {
    id
    name
  }
}

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

  1. Configura una regla de validació per limitar la profunditat de les consultes a 5.
  2. 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ó

  1. Crea un DataLoader per carregar usuaris en lots.
  2. 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.

© Copyright 2024. Tots els drets reservats