tutorial

9 Membuat HTTP Server Dasar untuk GraphQL Endpoint

9 Membuat HTTP Server Dasar untuk GraphQL Endpoint

Implementasi GraphQL tidak lagi membutuhkan framework besar. Kita bisa membuat HTTP server dasar untuk melayani query GraphQL dengan efisien dan mudah dipahami. Artikel ini akan membimbing kamu dari nol hingga HTTP server GraphQL sederhana siap pakai, lengkap dengan contoh kode, simulasi query, dan diagram alur.


Pengantar

GraphQL menjadi standar baru untuk API modern. Banyak developer ingin mencoba atau men-deploy endpoint GraphQL tanpa repot dengan framework berat seperti Apollo Server atau Relay. Kadang kita hanya butuh endpoint sederhana untuk prototipe, mocking backend, atau learning-by-doing. Apapun alasannya, konsep dasarnya sama: kita butuh HTTP server yang mampu menerima request dan merespons dengan data sesuai query GraphQL.

Artikel ini akan membahas cara membangun HTTP server dasar untuk GraphQL menggunakan Node.js dan library graphql-js. Fokus kita bukan pada fancy features, tapi pada konsep dan implementasi core GraphQL endpoint: request masuk lewat HTTP, query diproses, response dikirim balik.


1. Prasyarat

Untuk mengikuti tutorial ini, kamu hanya membutuhkan:

  • Pengetahuan dasar JavaScript/Node.js
  • Node.js >= v14
  • Library graphql dari npm

Installasi GraphQL:

npm init -y
npm install graphql

Untuk HTTP server, kita cukup pakai module built-in http dari Node.


2. Struktur Minimalist HTTP Server

Tujuan utama adalah menerima request POST di /graphql, membaca query dari request body, lalu proses dan kirim balik hasilnya. Tidak perlu routing yang rumit.

const http = require('http');
const { graphql, buildSchema } = require('graphql');

// 1. Define schema & resolver
const schema = buildSchema(`
  type Query {
    hello: String
  }
`);
const rootValue = {
  hello: () => 'Hello, world!'
};

// 2. HTTP server declaration
const server = http.createServer(async (req, res) => {
  if (req.method === 'POST' && req.url === '/graphql') {
    let body = '';
    req.on('data', chunk => body += chunk);
    req.on('end', async () => {
      try {
        const { query, variables } = JSON.parse(body);

        // 3. Core: GraphQL execution
        const result = await graphql({
          schema,
          source: query,
          rootValue,
          variableValues: variables
        });

        // Response
        res.writeHead(200, { 'Content-Type': 'application/json' });
        res.end(JSON.stringify(result));
      } catch (err) {
        res.writeHead(400);
        res.end(JSON.stringify({ errors: [{ message: err.message }] }));
      }
    });
  } else {
    res.writeHead(404);
    res.end();
  }
});

server.listen(4000, () => {
  console.log('GraphQL server running at http://localhost:4000/graphql');
});

3. Bagaimana Flow-nya?

Mari kita visualisasikan alur request-response HTTP untuk endpoint ini dengan diagram mermaid:

sequenceDiagram
    client->>server: POST /graphql {query, variables}
    server->>server: Parse body JSON
    server->>server: graphql({schema, query, rootValue})
    server->>server: Execute resolver
    server->>client: HTTP 200 {data, errors}

Garis besarnya:

  1. Client mengirim POST ke endpoint /graphql.
  2. Server membaca query dari body (JSON).
  3. Eksekusi query menggunakan fungsi graphql.
  4. Kirim hasil (data, dan/atau errors) ke client.

4. Simulasi Request

Untuk mencoba endpoint ini, gunakan cURL atau GraphQL client seperti Insomnia/Postman.

curl -X POST http://localhost:4000/graphql \
  -H "Content-Type: application/json" \
  -d '{"query": "{ hello }"}'

Respon yang diharapkan:

{
  "data": {
    "hello": "Hello, world!"
  }
}

5. Menambah Query & Parameter

Schema dan resolver bisa dengan mudah dikembangkan. Contoh: menambah query dengan argumen.

const schema = buildSchema(`
  type Query {
    hello(name: String): String
  }
`);

const rootValue = {
  hello: ({ name }) => `Hello, ${name || "world"}!`
};

Request:

{
  "query": "{ hello(name: \"Agus\") }"
}

Response:

{
  "data": {
    "hello": "Hello, Agus!"
  }
}

6. Menangani Error

Misal query tidak valid:

{
  "query": "{ foo }"
}

Output:

{
  "errors": [
    {
      "message": "Cannot query field \"foo\" on type \"Query\"."
    }
  ]
}

7. Penjelasan Tabel: Struktur Request & Response

HTTP MethodPathContent-TypeBody (JSON)Response (JSON)
POST/graphqlapplication/json{ “query”: “…”, “variables”: { … } }{ “data”: {…}, “errors”: […] }

8. Mengembangkan Schema Lebih Jauh

GraphQL mendorong schema yang ekspresif. Berikut contoh schema dan resolver sederhana yang sedikit kompleks.

const schema = buildSchema(`
  type User {
    id: ID
    name: String
    age: Int
  }
  type Query {
    user(id: ID!): User
    users: [User]
  }
`);

const users = [
  { id: "1", name: "Agus", age: 30 },
  { id: "2", name: "Budi", age: 25 }
];

const rootValue = {
  user: ({ id }) => users.find(u => u.id === id),
  users: () => users
};

Query:

{
  "query": "{ users { name, age } }"
}

Response:

{
  "data": {
    "users": [
      { "name": "Agus", "age": 30 },
      { "name": "Budi", "age": 25 }
    ]
  }
}

9. Saran Produksi & Kesimpulan

HTTP server dasar ini cocok untuk prototyping, POC, atau internal tools. Untuk deployment production, minimal tambahkan:

  • Validasi payload dan ukuran body (security)
  • Implementasi logging dan error tracking
  • Support untuk CORS jika dibutuhkan akses cross-origin
  • Rate-limiting bila diakses publik

Namun, core logic tidak berubah banyak: accept query, execute, respond. Kamu bisa embed kode ini di service/worker tanpa banyak overhead.

💡 Kesimpulan

Tanpa framework besar, kita dapat membuat HTTP server GraphQL yang ringan dan mudah dipahami. Mulai dari pemrosesan HTTP request sederhana, parsing, eksekusi query, hingga mengembalikan response. Kunci penting adalah memahami alur dasar GraphQL, tidak hanya menggunakan tool siap pakai.

Next: Kamu bisa memperluas server ini dengan fitur authentication, schema federation, atau menyambungkan resolver ke database.


Referensi


Semoga bermanfaat, dan happy hacking dengan GraphQL—dari engineer, untuk engineer!

comments powered by Disqus