Use Cases (Diperbarui: 3/6/2026)

Pengembangan gRPC dengan Claude Code: Protobuf, streaming, operasi

Bangun layanan gRPC yang bisa dijalankan dengan Claude Code, Protobuf, tenggat, streaming, auth, dan observability.

Pengembangan gRPC dengan Claude Code: Protobuf, streaming, operasi

Mulai Dari Kontrak, Bukan Dari Server

gRPC adalah kerangka panggilan prosedur jarak jauh. Klien memanggil metode di layanan lain seperti fungsi lokal, tetapi komunikasi sebenarnya berjalan melalui jaringan. Protocol Buffers mendefinisikan kontrak: layanan, metode, pesan permintaan, pesan respons, dan nomor field. Claude Code sebaiknya memahami kontrak ini sebelum menulis server dan klien.

Gunakan dokumentasi resmi sebagai acuan: gRPC Introduction, Core concepts, Node basics, Deadlines, Status Codes, Authentication, OpenTelemetry Metrics, dan Protocol Buffers proto3 guide.

Untuk konteks ClaudeCodeLab, lanjutkan dengan pengembangan API produksi, microservices dengan Claude Code, strategi versi API, dan strategi testing.

Kasus Penggunaan Nyata

Jangan memilih gRPC hanya karena terdengar cepat. Pilih ketika kontrak bertipe, status gagal yang jelas, dan konsistensi lintas bahasa benar-benar membantu.

KasusMengapa gRPC cocokTugas untuk Claude Code
Layanan internal pesanan, stok, tagihanKontrak mengurangi perbedaan antar timMenulis .proto, server, klien, dan tabel status
Ekspor data besarStreaming server menghindari satu respons raksasaMerancang returns (stream Item) dan pembatalan
Tim dengan Go, Node, PythonSatu skema memandu beberapa klienMendokumentasikan perintah generasi, folder, dan CI
Alat internal dan agen AIMetode eksplisit mengurangi panggilan ambiguMenambah klien contoh, metadata auth, tenggat, dan log

Catatan praktik dari Masa: metode Search yang terlalu luas terasa mudah pada awalnya, tetapi cepat sulit diubah. Pisahkan baca, buat, dan streaming lebih awal, lalu minta Claude Code mengikuti kontrak itu.

Contoh Node gRPC Yang Bisa Dijalankan

Contoh ini memakai @grpc/proto-loader, sehingga bukti lokal pertama tidak membutuhkan protoc.

mkdir claude-grpc-demo
cd claude-grpc-demo
npm init -y
npm install @grpc/grpc-js @grpc/proto-loader
mkdir proto

package.json:

{
  "type": "commonjs",
  "scripts": {
    "server": "node server.js",
    "client": "node client.js"
  },
  "dependencies": {
    "@grpc/grpc-js": "latest",
    "@grpc/proto-loader": "latest"
  }
}

proto/task.proto:

syntax = "proto3";

package tasks.v1;

service TaskService {
  rpc CreateTask(CreateTaskRequest) returns (Task);
  rpc GetTask(GetTaskRequest) returns (Task);
  rpc ListTasks(ListTasksRequest) returns (stream Task);
}

message Task {
  string id = 1;
  string title = 2;
  string status = 3;
  int64 created_at_unix = 4;
}

message CreateTaskRequest {
  string title = 1;
}

message GetTaskRequest {
  string id = 1;
}

message ListTasksRequest {
  int32 limit = 1;
}

server.js:

const path = require("node:path");
const { randomUUID } = require("node:crypto");
const grpc = require("@grpc/grpc-js");
const protoLoader = require("@grpc/proto-loader");

const PROTO_PATH = path.join(__dirname, "proto", "task.proto");
const packageDefinition = protoLoader.loadSync(PROTO_PATH, {
  keepCase: false,
  longs: String,
  enums: String,
  defaults: true,
  oneofs: true,
});
const taskProto = grpc.loadPackageDefinition(packageDefinition).tasks.v1;
const token = process.env.DEMO_TOKEN || "dev-token";
const tasks = new Map();

function grpcError(code, message) {
  const error = new Error(message);
  error.code = code;
  return error;
}

function assertAuthenticated(call) {
  const value = call.metadata.get("authorization")[0];
  if (value !== `Bearer ${token}`) {
    throw grpcError(grpc.status.UNAUTHENTICATED, "UNAUTHENTICATED");
  }
}

function createTask(call, callback) {
  try {
    assertAuthenticated(call);
    const title = String(call.request.title || "").trim();
    if (!title) {
      return callback(grpcError(grpc.status.INVALID_ARGUMENT, "INVALID_ARGUMENT: title"));
    }

    const task = {
      id: randomUUID(),
      title,
      status: "OPEN",
      createdAtUnix: String(Math.floor(Date.now() / 1000)),
    };
    tasks.set(task.id, task);
    callback(null, task);
  } catch (error) {
    callback(error);
  }
}

function getTask(call, callback) {
  try {
    assertAuthenticated(call);
    const task = tasks.get(call.request.id);
    if (!task) {
      return callback(grpcError(grpc.status.NOT_FOUND, "NOT_FOUND: task"));
    }
    callback(null, task);
  } catch (error) {
    callback(error);
  }
}

function listTasks(call) {
  try {
    assertAuthenticated(call);
    const limit = Math.min(Math.max(Number(call.request.limit) || 10, 1), 100);
    for (const task of Array.from(tasks.values()).slice(0, limit)) {
      call.write(task);
    }
    call.end();
  } catch (error) {
    call.destroy(error);
  }
}

const server = new grpc.Server();
server.addService(taskProto.TaskService.service, { createTask, getTask, listTasks });
server.bindAsync("127.0.0.1:50051", grpc.ServerCredentials.createInsecure(), (error, port) => {
  if (error) throw error;
  console.log(`TaskService listening on ${port}`);
});

client.js:

const path = require("node:path");
const grpc = require("@grpc/grpc-js");
const protoLoader = require("@grpc/proto-loader");

const PROTO_PATH = path.join(__dirname, "proto", "task.proto");
const packageDefinition = protoLoader.loadSync(PROTO_PATH, {
  keepCase: false,
  longs: String,
  enums: String,
  defaults: true,
  oneofs: true,
});
const taskProto = grpc.loadPackageDefinition(packageDefinition).tasks.v1;
const client = new taskProto.TaskService("127.0.0.1:50051", grpc.credentials.createInsecure());
const metadata = new grpc.Metadata();
metadata.set("authorization", `Bearer ${process.env.DEMO_TOKEN || "dev-token"}`);

function deadline(ms) {
  return new Date(Date.now() + ms);
}

function createTask(title) {
  return new Promise((resolve, reject) => {
    client.createTask({ title }, metadata, { deadline: deadline(1000) }, (error, task) => {
      if (error) return reject(error);
      resolve(task);
    });
  });
}

function getTask(id) {
  return new Promise((resolve, reject) => {
    client.getTask({ id }, metadata, { deadline: deadline(1000) }, (error, task) => {
      if (error) return reject(error);
      resolve(task);
    });
  });
}

function listTasks(limit) {
  return new Promise((resolve, reject) => {
    const rows = [];
    const stream = client.listTasks({ limit }, metadata, { deadline: deadline(1000) });
    stream.on("data", (task) => rows.push(task));
    stream.on("error", reject);
    stream.on("end", () => resolve(rows));
  });
}

async function main() {
  const created = await createTask("Claude Code gRPC");
  const fetched = await getTask(created.id);
  const rows = await listTasks(10);
  console.log(JSON.stringify({ created, fetched, streamed: rows.length }, null, 2));
  client.close();
}

main().catch((error) => {
  console.error(error.code, error.details || error.message);
  client.close();
  process.exitCode = 1;
});

Terminal pertama:

npm run server

Terminal kedua:

npm run client

Evolusi Skema, Keamanan, Dan Kegagalan

Dalam Protocol Buffers, kesalahan paling berbahaya adalah memakai ulang nomor field. Nomor yang sudah dirilis jangan diubah. Jika field dihapus, simpan nomor dan namanya dengan reserved.

message Task {
  string id = 1;
  string title = 2;
  string status = 3;
  int64 created_at_unix = 4;
  optional string assignee_email = 5;
  reserved 6, 7;
  reserved "owner_email";
}

Tenggat harus eksplisit. Dokumentasi gRPC menjelaskan bahwa klien tanpa tenggat dapat menunggu tanpa batas yang realistis. Streaming berguna untuk ekspor dan progres, tetapi harus menangani pembatalan dan tidak boleh menahan seluruh hasil di memori.

Contoh memakai createInsecure() hanya untuk lokal. Produksi harus memakai TLS: grpc.ServerCredentials.createSsl(...) di server dan grpc.credentials.createSsl(rootCert) di klien. Token pada metadata tidak cukup jika kanal tidak terenkripsi.

Observability perlu menunjukkan metode, status, durasi, pembatalan, tenggat habis, dan backend tidak tersedia. Metrik gRPC OpenTelemetry adalah dasar yang baik. Jangan mengubah semua kegagalan menjadi UNKNOWN; bedakan INVALID_ARGUMENT, NOT_FOUND, UNAUTHENTICATED, DEADLINE_EXCEEDED, UNAVAILABLE, dan RESOURCE_EXHAUSTED. Panggilan tulis sebaiknya diulang otomatis hanya jika ada idempotency key.

Prompt Untuk Claude Code

Implementasikan gRPC TaskService.
Syarat:
- Buat proto/task.proto terlebih dahulu
- Gunakan Node.js, @grpc/grpc-js, dan @grpc/proto-loader
- Implementasikan CreateTask, GetTask, dan ListTasks server streaming
- Tambahkan deadline pada semua RPC klien
- Validasi authorization metadata
- Dokumentasikan bahwa produksi harus mengganti createInsecure dengan TLS
- Jalankan npm run client dan laporkan output
File yang boleh diubah:
- proto/task.proto
- server.js
- client.js
- package.json

Untuk peninjauan:

Tinjau implementasi gRPC ini dengan findings first.
Periksa reuse nomor field, schema evolution, deadline, cancellation,
status code, perilaku memori saat streaming, TLS/auth, dan observability.
Urutkan berdasarkan tingkat bahaya dan sertakan file.

CTA Dan Hasil Verifikasi

Jika belajar sendiri, mulai dari cheatsheet Claude Code gratis lalu ubah contoh ini menjadi proyek latihan kecil. Tim yang perlu mengatur .proto, gerbang CI, prompt review, TLS, dan observability bisa melanjutkan ke pelatihan dan konsultasi Claude Code. Materi yang bisa dipakai ulang tersedia di produk ClaudeCodeLab.

Dalam pembaruan ini, contoh dijalankan di direktori sementara dengan Node v24.14.1 dan npm 11.11.0. npm install, node server.js, dan node client.js berhasil, lalu klien menampilkan created, fetched, dan streamed: 1. Mesin ini tidak memiliki go, protoc, atau plugin Protobuf untuk Go, sehingga artikel memakai jalur Node yang benar-benar dapat diverifikasi di sini.

#Claude Code #gRPC #Protocol Buffers #microservices #backend
Gratis

PDF gratis: cheatsheet Claude Code

Masukkan email dan unduh satu halaman berisi command, kebiasaan review, dan workflow aman.

Kami menjaga datamu dan tidak mengirim spam.

Masa

Tentang penulis

Masa

Engineer yang berfokus pada workflow Claude Code praktis dan adopsi tim.