tutorial

51 Konfigurasi GraphQL Server untuk Production

51 Konfigurasi GraphQL Server untuk Production

GraphQL kini menjadi salah satu tulang punggung utama dalam membangun API yang skalabel dan fleksibel. Namun, mengoperasikan GraphQL server pada lingkungan production memerlukan perhatian ekstra, terutama terkait konfigurasi. Banyak tim berakhir mengalami downtime, kebocoran data, atau performa lambat, karena kurang maksimalnya konfigurasi GraphQL saat deployment production.

Di artikel ini, saya akan mengulas 51 konfigurasi yang wajib Anda perhatikan, lengkap dengan best-practices, contoh kode, serta trik-trik dari pengalaman pribadi dan teman-teman di komunitas.


1. Aktifkan Query Depth Limiting

Batasi kedalaman query untuk mencegah serangan DoS akibat nested query berlebihan.

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

app.use(
  '/graphql',
  graphqlHTTP({
    schema,
    validationRules: [depthLimit(5)],
  }),
);

2. Batasan Query Complexity

Cegah over-fetching data dengan pembatasan “berat” query.

const { createComplexityRule } = require('graphql-validation-complexity');
app.use(
  '/graphql',
  graphqlHTTP({
    schema,
    validationRules: [
      createComplexityRule({
        maximumComplexity: 1000,
        estimators: [...],
      }),
    ],
  }),
);

3. Disable Playground/GraphiQL di Production

Pastikan endpoint tools development tidak aktif.

const isProd = process.env.NODE_ENV === 'production';
app.use(
  '/graphql',
  graphqlHTTP({
    schema,
    graphiql: !isProd,
  }),
);

4. Implementasi Persisted Queries

Hanya allow query yang sudah didaftarkan.

// With Apollo Server
const apq = require("apollo-server-plugin-persisted-queries");
const server = new ApolloServer({
  schema,
  plugins: [apq()],
});

5. Custom Error Masking

Jangan expose stack trace di response.

const formatError = (err) => {
  if (process.env.NODE_ENV === 'production') {
    return new Error('Internal server error');
  }
  return err;
}
// Gunakan formatError di Apollo/Express

6. Limit Req Size

Jangan biarkan request body terlalu besar.

app.use(express.json({ limit: '1mb' }));

7. Rate Limiting

Prevent brute-force via API.

const rateLimit = require('express-rate-limit');
app.use('/graphql', rateLimit({
  windowMs: 60 * 1000,
  max: 20,
}));

8. CORS Policy Strict

Pastikan origin yang boleh akses.

app.use(cors({ origin: ['https://mydomain.com'], credentials: true }));

9. Implementasi Dataloader

Batching dan caching data request.

const DataLoader = require('dataloader');
const userLoader = new DataLoader(userIds => batchGetUsers(userIds));

10. Disable Introspection di Production

Kecuali benar-benar diperlukan.

const { NoSchemaIntrospectionCustomRule } = require('graphql');
app.use('/graphql', graphqlHTTP({
  validationRules: [NoSchemaIntrospectionCustomRule],
}));

11. Tracing & Monitoring

Integrasi dengan APM seperti Datadog, Sentry, atau Prometheus.

import { ApolloServerPluginUsageReporting } from "apollo-server-core";
const server = new ApolloServer({
  plugins: [ApolloServerPluginUsageReporting()],
});

12. Authentication Wajib

Aktifkan JWT, OAuth, atau sesi sebelum resolvers.


13. Authorization Granular

Gunakan directive misal @auth(role: ADMIN) di typeGraphQL/Apollo.


14. Disable HTTP GET untuk mutation

Mutasi sebaiknya hanya POST.


15. Compress Response

Gunakan gzip/brotli untuk response besar.


16. Implement Cache Layer

Cache di resolver, untuk data read-heavy.


17. Error Logging

Integrasi dengan Winston, Bunyan, atau ELK stack.


18. Set Query Timeout

Jangan biarkan query jalan lama.

// Pseudo code:
const TIMEOUT = 5 * 1000; 
await Promise.race([resolveQuery(), wait(TIMEOUT)]);

19–25: Advanced Security & Isolation

#FiturCatatan
19Helmet.js HeadersTambahkan HTTP sec headers
20Disable ‘X-Powered-By’Hindari expose tech
21Content Security PolicyHindari XSS
22IP AllowlistRestriksi akses tertentu
23Secure CookiesGunakan Secure+HttpOnly
24Input ValidationGunakan Joi/Yup
25Sanitize InputsCegah injeksi

26–30: Schema Management

  1. Schema Registry: Gunakan Apollo/Hasura schema registry.
  2. Versioning: Tanda versi encoder di header.
  3. Deprecation: Tandai field & types deprecated.
  4. Documentation Otomatis: Integrasi dengan GraphQL Voyager/SpectaQL.
  5. Schema Diff Monitoring: Integrasi schema diff dari Github Action.

31–35: Observability

  1. Custom Metrics: Implement counter untuk jumlah tiap operation.
  2. Distributed Tracing: Gunakan OpenTelemetry.
  3. Audit Log: Catat siapa akses apa dan kapan.
  4. Ops Dashboard: Visualisasi performa & error rate.
  5. Alerting: Setup threshold alert di Grafana/Prometheus.

36–39: Production Infra & Deployment

  1. Readiness/Liveness Probes: K8S health check endpoint.
  2. Rolling Update: Tidak down saat deploy.
  3. Auto Scaling: Berdasar rate QPS.
  4. Blue/Green Deployment: Cegah downtime dan mitigasi rollback.

40–43: CDN dan Edge Cache

  1. Cache Dokumentasi & Introspection
  2. Stale-While-Revalidate di Proxy
  3. Edge Rate Limiting: di CDN (Cloudflare/Akamai)
  4. GraphQL CDN Routing: Misal di Cloudflare Workers untuk geo-routing.

44–46: Environment Separation

  1. Strict ENV File: Jangan campur config production dan staging/dev.
  2. Sensitive Secret Management: Gunakan vault, jangan letakkan API secret di codebase.
  3. Config Auditing: Regularly review config change.

47–48: Testing Strategy

  1. Contract Test: Gunakan GraphQL Faker/Mock untuk client.
  2. Load Test: Dengan Artillery atau k6.

49–50: Performance Optimization

  1. Resolver: Avoid N+1: Selalu gunakan Dataloader atau aggregate SQL query.
  2. Schema Stitching & Federation: Untuk microservices breakdown.

51: Graceful Shutdown

Handle signal seperti SIGINT agar request berjalan selesai sebelum proses mati.

process.on('SIGINT', () => {
  server.stop().then(() => {
    process.exit(0);
  });
});

Alur Diagram Konfigurasi Deployment

flowchart LR
  A[Start Development]
  B[Review Config]
  C[Automated Deployment]
  D{Environment?}
  E[Pre-prod Checks]
  F[Production Checks]
  G[Run Health Probe]
  H[Launch]
  
  A-->B
  B-->C
  C-->D
  D-->|Staging|E
  D-->|Production|F
  E-->|Pass|G
  F-->|Pass|G
  G-->H

Kesimpulan

Men-deploy GraphQL server di production bukan sekedar menekan tombol deploy. Ada banyak aspek konfigurasi yang jika dilewatkan, bisa merugikan bisnis—dan nama baik engineering tim Anda.

Kuncinya:

  • Batasi eksplorasi query (introspection dan nesting),
  • Proteksi endpoint dengan security layer,
  • Monitoring untuk observability,
  • Pengelolaan schema yang disiplin,
  • Dan, deployment pipeline yang solid.

Checklist ini tidak hanya mencegah error dan kebocoran, tapi juga membantu tim fokus pada value delivery dan ekspansi bisnis. Apakah Anda sudah siap membawa GraphQL server ke production-level yang sesungguhnya? Selalu revisi, diskusikan dengan tim, dan pastikan checklist ini menjadi bagian wajib di pipeline CI/CD Anda.


Pro Tips:
Cek juga awesome-graphql-security untuk update tools terbaru yang bisa langsung Anda integrasikan!


Jika ada tambahan pengalaman konfigurasi, silakan share di komentar. Happy scaling GraphQL! 🚀

comments powered by Disqus