Use Cases (Actualizado: 3/6/2026)

Desarrollo gRPC con Claude Code: Protobuf, transmisión y operación

Crea un servicio gRPC ejecutable con Claude Code, Protobuf, plazos, transmisión, autenticación y observabilidad.

Desarrollo gRPC con Claude Code: Protobuf, transmisión y operación

Empieza por el contrato, no por el servidor

gRPC es un marco de llamadas remotas: el cliente invoca un método de otro servicio como si fuera una función local, pero la comunicación ocurre por red. Protocol Buffers define el contrato: servicios, métodos, mensajes de petición, mensajes de respuesta y números de campo. Claude Code puede escribir mucho código rápido, pero si ese contrato queda ambiguo, también quedarán ambiguos el servidor, el cliente y las pruebas.

Trabaja con documentación oficial abierta: gRPC Introduction, Core concepts, Node basics, Deadlines, Status Codes, Authentication, OpenTelemetry Metrics y la guía de Protocol Buffers proto3.

Para ampliar dentro de ClaudeCodeLab, combina esta guía con desarrollo de API de producción, microservicios con Claude Code, versionado de API y estrategias de prueba.

Casos de uso reales

No elijas gRPC solo porque “es rápido”. Elige gRPC cuando el contrato tipado, los fallos explícitos y la coherencia entre lenguajes aportan valor.

CasoPor qué encaja gRPCQué pedir a Claude Code
Servicios internos de pedidos, inventario y facturaciónEl contrato reduce desalineación entre equiposCrear .proto, servidor, cliente y tabla de códigos
Exportaciones grandesLa transmisión del servidor evita una respuesta giganteDiseñar returns (stream Item) y cancelación
Equipos con Go, Node y PythonUn esquema puede guiar varios clientesDocumentar generación, carpetas y CI
Herramientas internas y agentes de IALos métodos explícitos reducen llamadas ambiguasAñadir cliente de ejemplo, metadatos de autenticación, plazos y registros

La lección práctica de Masa es que un método Search demasiado amplio parece cómodo al principio, pero se vuelve difícil de versionar. Separar lectura, creación y transmisión antes de pedir código a Claude Code deja revisiones más pequeñas.

Ejemplo gRPC en Node listo para copiar

Este ejemplo usa @grpc/proto-loader, así que no necesita protoc para la primera prueba local.

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;
});

En una terminal:

npm run server

En otra terminal:

npm run client

Evolución, seguridad y fallos

En Protocol Buffers, no reutilices números de campo. Si eliminas un campo, reserva su número y su nombre. Para nuevos datos, añade un número nuevo; si necesitas distinguir “no enviado” de “vacío”, usa presencia explícita.

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";
}

Los plazos son parte del diseño, no un detalle final. La documentación de gRPC indica que, sin plazo, un cliente puede esperar indefinidamente. La transmisión sirve para exportaciones y progreso, pero debe manejar cancelación y no acumular todo en memoria.

El ejemplo usa createInsecure() solo para la prueba local. En producción usa TLS: grpc.ServerCredentials.createSsl(...) en el servidor y grpc.credentials.createSsl(rootCert) en el cliente. Un token en metadatos no protege nada si el canal no está cifrado.

La observabilidad debe incluir método, estado, duración, cancelación, vencimiento de plazo y backend no disponible. Los indicadores gRPC de OpenTelemetry son una base práctica. No conviertas todos los errores en UNKNOWN; separa INVALID_ARGUMENT, NOT_FOUND, UNAUTHENTICATED, DEADLINE_EXCEEDED, UNAVAILABLE y RESOURCE_EXHAUSTED. Reintenta escrituras solo con clave de idempotencia.

Prompt para Claude Code

Implementa gRPC TaskService.
Condiciones:
- Crear primero proto/task.proto
- Usar Node.js, @grpc/grpc-js y @grpc/proto-loader
- Implementar CreateTask, GetTask y ListTasks con transmisión del servidor
- Añadir deadline a todos los RPC del cliente
- Validar authorization metadata
- Documentar que producción debe sustituir createInsecure por TLS
- Ejecutar npm run client y reportar la salida
Archivos editables:
- proto/task.proto
- server.js
- client.js
- package.json

Para revisión:

Revisa esta implementación gRPC con findings first.
Comprueba reutilización de números de campo, evolución del esquema,
deadline, cancellation, status code, memoria en transmisión,
TLS/auth y observability. Ordena por gravedad y cita archivos.

CTA y resultado verificado

Si estás aprendiendo solo, empieza con la chuleta gratuita de Claude Code y adapta este ejemplo en un proyecto desechable. Si tu equipo necesita gobernanza de .proto, puertas de CI, prompts de revisión, TLS y observabilidad, revisa formación y consultoría Claude Code. Para material reutilizable, usa productos ClaudeCodeLab.

Para esta actualización, el ejemplo se ejecutó en un directorio temporal con Node v24.14.1 y npm 11.11.0. npm install, node server.js y node client.js terminaron bien, y el cliente mostró created, fetched y streamed: 1. En esta máquina no estaban disponibles go, protoc ni los complementos Protobuf para Go, así que el artículo se limita al camino Node que sí pudo verificarse.

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

PDF gratis: cheatsheet de Claude Code

Introduce tu email y descarga una hoja con comandos, hábitos de revisión y flujos seguros.

Cuidamos tus datos y no enviamos spam.

Masa

Sobre el autor

Masa

Ingeniero enfocado en workflows prácticos con Claude Code.