Learning
GraphQL

Gyakori hibák

Tipikus GraphQL csapdák teljesítményben, biztonságban és karbantarthatóságban.

Gyakori hibák

1. N+1 lekérdezési probléma figyelmen kívül hagyása

A leggyakoribb teljesítményprobléma. Mindig használj DataLoadert a kapcsolódó objektumok batch-elésére.

// ❌ Minden Post resolverje külön DB-lekérdezést indít
Post: {
  author: (parent, _, { db }) => db.users.findById(parent.authorId),
}

// ✅ DataLoaderrel batch-elt lekérdezés
Post: {
  author: (parent, _, { loaders }) => loaders.user.load(parent.authorId),
}

2. A context nem kerül felhasználásra

A context a megosztott erőforrások átadásának helyes módja – ne hozz létre új DB-kapcsolatot minden resolverben.

// ❌ Új kapcsolat minden resolverben
Query: {
  user: async (_, { id }) => {
    const db = new Database();
    return db.users.findById(id);
  },
}

// ✅ Context-ből kapott kapcsolat
Query: {
  user: async (_, { id }, { db }) => {
    return db.users.findById(id);
  },
}

3. Érzékeny adatok expozálása

# ❌ Jelszó hash a sémában
type User {
  id: ID!
  passwordHash: String! # SOHA ne tedd elérhetővé!
}

# ✅ Csak szükséges mezők
type User {
  id: ID!
  name: String!
  email: String!
}

4. Túl nagy, monolitikus séma

Érdemes a sémát modulokra bontani és összefűzni:

// ❌ Egy hatalmas sémafájl
const typeDefs = `
  # 1000 sor...
`;

// ✅ Moduláris séma
const { mergeTypeDefs, mergeResolvers } = require('@graphql-tools/merge');

const typeDefs = mergeTypeDefs([userTypeDefs, postTypeDefs, commentTypeDefs]);
const resolvers = mergeResolvers([userResolvers, postResolvers, commentResolvers]);

5. Cache stratégia hiánya

A GraphQL egyetlen végpontot használ, ezért a HTTP-szintű cache nem működik úgy, mint REST-nél. Explicit cache stratégiát kell tervezni.

// Apollo Client cache stratégia beállítása
const client = new ApolloClient({
  cache: new InMemoryCache({
    typePolicies: {
      User: {
        keyFields: ['id'], // Cache kulcs
      },
      Post: {
        keyFields: ['id'],
        fields: {
          comments: {
            merge(existing = [], incoming) {
              return [...existing, ...incoming];
            },
          },
        },
      },
    },
  }),
});

6. Subscription memóriaszivárgás

Mindig iratkozz le a subscriptionről, ha a komponens unmountolódik:

// ❌ Nem iratkozik le
useEffect(() => {
  const sub = subscribeToMore({ ... });
}, []);

// ✅ Cleanup függvénnyel
useEffect(() => {
  const unsubscribe = subscribeToMore({ ... });
  return () => unsubscribe();
}, []);

Rövid összefoglaló

  • Az N+1 probléma a leggyakoribb teljesítményprobléma – DataLoaderrel oldható meg.
  • A context a helyes módja a megosztott erőforrások átadásának.
  • Soha ne tedd elérhetővé az érzékeny adatokat (jelszó hash, belső ID-k) a sémában.
  • Nagy projekteknél a sémát modulokra bontva kezeld.
  • Tervezz explicit cache stratégiát – a HTTP cache nem működik GraphQL-nél.
  • Subscription esetén mindig iratkozz le, amikor a komponens eltűnik.

On this page