Ir al contenido
RT
Volver

Bindings en Cloudflare Workers: permiso + API en env

“Binding” conviene dejarlo en inglés.

Traducirlo como “enchufe” puede sonar simpático y confunde. Un binding no es un cable ni un conector visual. En Cloudflare Workers es una conexión declarada entre tu Worker y un recurso.

Cloudflare lo describe como combinación de permiso y API. En la práctica:

configuras que un Worker puede usar un recurso, y en código lo recibes dentro de env.

env.MY_BUCKET
env.EMAIL_QUEUE
env.COUNTERS
env.AI

Si vienes de Workers 101, esto es el siguiente paso: el Worker deja de ser “solo fetch” y se convierte en una puerta con capacidades.

El problema que resuelve

Sin bindings, muchas integraciones terminan así:

const bucketUrl = "https://...";
const apiKey = "abc...";
const queueName = "prod-email-queue";

Eso se vuelve frágil:

Con bindings, la dependencia queda declarada en la configuración del Worker. Tu código no inventa la conexión a mano para recursos de Cloudflare: usa la API que aparece en env.

No digas / Mejor

No digas:

“El binding es un enchufe seguro.”

Mejor:

“El binding es una capacidad declarada que el Worker recibe en env.”

Ejemplo de arquitectura legible:

Worker "api" tiene:
- ASSETS_BUCKET
- EMAIL_QUEUE
- USER_COUNTERS

Si dibujas los bindings, empiezas a ver el sistema.

Ejemplo: signup → Queue

type SignupJob = {
  email: string;
  source: string;
};

export interface Env {
  SIGNUP_QUEUE: Queue<SignupJob>;
}

export default {
  async fetch(request, env): Promise<Response> {
    const body = await request.json<SignupJob>();

    await env.SIGNUP_QUEUE.send({
      email: body.email,
      source: body.source ?? "web",
    });

    return Response.json({ accepted: true }, { status: 202 });
  },
} satisfies ExportedHandler<Env>;

La línea que importa:

await env.SIGNUP_QUEUE.send(...);

SIGNUP_QUEUE existe porque fue declarado como binding — no porque el código “descubrió” una cola mágica.

Ejemplo: R2

R2 es object storage. Si el bucket está bound, el Worker lo usa directo:

export interface Env {
  ASSETS: R2Bucket;
}

export default {
  async fetch(request, env): Promise<Response> {
    if (request.method !== "PUT") {
      return new Response("Use PUT", { status: 405 });
    }

    const key = new URL(request.url).pathname.slice(1);
    await env.ASSETS.put(key, request.body);

    return Response.json({ ok: true, key });
  },
} satisfies ExportedHandler<Env>;

No estás inventando un cliente HTTP con tokens hardcodeados. Estás usando una capacidad configurada para ese Worker en ese ambiente.

Bindings como herramienta de diseño

Pregunta útil:

¿Qué capacidades necesita este Worker?

AppCapacidades típicas
API de imágenesR2 + Queue (thumbnails) + D1 (metadata)
ChatDurable Object (sala) + Queue (analytics async)
Feature de IAAI Gateway + R2 (resultados) + Queue (jobs largos)

Si no puedes listar los bindings, probablemente hay arquitectura escondida.

Antipatrón: demasiados bindings en un solo Worker

API Worker:
- USERS_DB
- EMAIL_QUEUE
- IMAGE_BUCKET
- CRM_SECRET
- ANALYTICS_QUEUE
- CHAT_ROOM
- AI_GATEWAY
- BILLING_SERVICE

No siempre está mal. Pero pregunta:

¿Sigue siendo una responsabilidad clara?

Si no, separa. Un binding por recurso no justifica un god-Worker.

Ambientes: el binding mismo, el recurso no

El nombre en código puede ser EMAIL_QUEUE en todos lados. El recurso real debe cambiar por ambiente:

EMAIL_QUEUE → cola de prod
EMAIL_QUEUE → cola de staging
EMAIL_QUEUE → cola de preview

Tu staging no debería escribir en la cola de producción por accidente. Preview no debería tocar el bucket real de clientes.

Cómo nombrarlos

Buenos:

RECEIPT_QUEUE
PRODUCT_IMAGES
USER_COUNTERS
AI_GATEWAY

Flojos:

DATA
THING
BUCKET2
PROD_STUFF

El nombre del binding es documentación operativa. Trátalo como tal.

Checklist antes de publicar

  1. Cada binding tiene un nombre claro.
  2. Dev / staging / prod apuntan a recursos correctos.
  3. Los secrets no están hardcodeados.
  4. El Worker maneja fallos del recurso.
  5. Los logs dicen qué dependencia falló.
  6. El Worker no mezcla responsabilidades a lo bestia.
  7. El tipo Env está actualizado.

La frase para recordar

binding = permiso + API disponible en env

Y el loop mental:

fetch() recibe el request
env trae las capacidades configuradas
los bindings muestran qué recursos usa el Worker

Serie Cloudflare para builders: Workers · Bindings · Durable Objects · Queues

Docs: Bindings · Wrangler config · Environments · Queues · R2 desde Workers


Share this post on:

Anterior
Durable Objects: identidad, estado y coordinación
Siguiente
Cloudflare Workers explicado sin buzzwords