Learning
GraphQL

GraphQL best practice-ek

Séma tervezés, változók, nullability, pagination, limiting és éles környezetes beállítások.

Best practice-ek

1. Séma tervezés: gondolkodj a kliensek szemszögéből

A GraphQL séma ne az adatbázis struktúráját tükrözze, hanem azt, amire a klienseknek szükségük van. Az adatbázis implementációs részlet – a séma az üzleti domaint modellezi.

# ❌ Adatbázis-orientált séma
type User {
  usr_id: Int!
  usr_name_first: String
  usr_name_last: String
  usr_email: String
}

# ✅ Kliensorientált séma
type User {
  id: ID!
  fullName: String!
  email: String!
}

2. Mindig használj változókat

# ❌ String interpoláció – SOHA ne csináld ezt
query {
  user(id: "123") { name }
}

# ✅ Változók – biztonságos és újrahasználható
query GetUser($id: ID!) {
  user(id: $id) { name }
}

3. Nullability körültekintő kezelése

A ! (non-null) jelölést csak ott használd, ahol valóban garantált, hogy az érték nem null. A túl sok ! töréspontokat okozhat a klienseken.

# Gondold végig: mikor lehet null egy mező?
type Post {
  id: ID!              # Mindig van ID
  title: String!       # Mindig van cím
  publishedAt: String  # Lehet null (vázlat állapotban)
  author: User         # Lehet null (törölt felhasználó)
}

4. Pagination minden listánál

Ne adj vissza korlátlan listákat – mindig adj pagination lehetőséget:

type Query {
  # ❌ Korlátlan lista
  posts: [Post!]!

  # ✅ Lapozható lista
  posts(page: Int = 1, limit: Int = 20): PostConnection!
}

5. Naming conventions

  • Típusok: PascalCase (User, BlogPost)
  • Mezők és argumentumok: camelCase (firstName, publishedAt)
  • Enumok: SCREAMING_SNAKE_CASE (ORDER_STATUS, USER_ROLE)
  • Queryök: főnév (GetUser, ListPosts)
  • Mutationök: ige + főnév (CreateUser, UpdatePost, DeleteComment)

6. Depth limiting (mélységkorlátozás)

Megakadályozza a szándékosan mélyre ágyazott, erőforrás-igényes lekérdezéseket:

const depthLimit = require('graphql-depth-limit');

const server = new ApolloServer({
  typeDefs,
  resolvers,
  validationRules: [depthLimit(5)],
});

7. Query complexity limiting

const { createComplexityLimitRule } = require('graphql-validation-complexity');

const server = new ApolloServer({
  typeDefs,
  resolvers,
  validationRules: [
    createComplexityLimitRule(1000, {
      onCost: (cost) => console.log('Query cost:', cost),
    }),
  ],
});

8. Perzistált lekérdezések (Persisted Queries)

Éles frontend alkalmazásban a lekérdezéseket hash alapján cache-eld, hogy ne kelljen minden kérésnél elküldeni a teljes query szöveget:

import { createPersistedQueryLink } from '@apollo/client/link/persisted-queries';
import { sha256 } from 'crypto-hash';

const link = createPersistedQueryLink({ sha256 }).concat(httpLink);

9. Introspection kikapcsolása éles környezetben

const server = new ApolloServer({
  typeDefs,
  resolvers,
  introspection: process.env.NODE_ENV !== 'production',
});

Rövid összefoglaló

  • A sémát a kliensek igényei köré tervezd, ne az adatbázis köré.
  • Mindig változókat használj, soha ne égesd bele az értékeket a lekérdezésbe.
  • Gondold végig a nullability-t: a ! jelölés töréspontokat okozhat.
  • Minden listás lekérdezésnél adj pagination lehetőséget.
  • Kövesd a naming convention-eket: PascalCase típusokhoz, camelCase mezőkhöz.
  • Éles környezetben kapcsold ki az introspection-t, és vezess be mélységkorlátozást.

On this page