Skip to contentjump to list
Voltar para o blog

Um Durable Object por Organização com Cloudflare e Drizzle ORM

Patrick Lima

Patrick Lima

Founder

Um Durable Object por Organização com Cloudflare e Drizzle ORM: Feedbacks Multi-Tenant na Prática

Inspirado pelo excelente artigo "One Database Per User with Cloudflare Durable Objects and Drizzle ORM" do Boris Tane, este post explora como aplicar um conceito similar no contexto de um sistema de feedback multi-tenant: um Durable Object por organização.

Ao invés de termos um banco de dados monolítico compartilhado entre todas as organizações, vamos isolar os dados por empresa, criando uma arquitetura mais segura, escalável e fácil de manter — especialmente útil quando lidamos com dados sensíveis como feedbacks de usuários.


🧱 A Arquitetura: Um DO por Organização

Cada organização (ou empresa) possui seu próprio DurableObject. Isso permite:

  • Armazenamento isolado de feedbacks por tenant
  • Redução de concorrência entre organizações
  • Possibilidade de evoluir schemas de forma independente
  • Escalabilidade natural, já que cada DO roda isoladamente

Na prática, cada organização tem uma instância própria de um DurableObject que contém seu banco de dados SQLite, via Drizzle ORM.


🌐 Roteando com Cloudflare Workers

Nosso Worker identifica a organização com base no subdomínio (ex: empresaA.superciclo.com, empresaB.superciclo.com) e roteia a requisição para o DurableObject correspondente.

// worker.ts
export default {
  async fetch(req: Request, env: Env) {
    const url = new URL(req.url);
    const orgSlug = getSubdomain(url.hostname);

    const id = env.FEEDBACK_OBJECT.idFromName(orgSlug);
    const stub = env.FEEDBACK_OBJECT.get(id);

    return stub.fetch(req);
  },
};

function getSubdomain(hostname: string): string {
  const parts = hostname.split(".");
  return parts.length > 2 ? parts[0] : "default";
}

🧠 A Lógica do Durable Object

Nosso DurableObject gerencia a criação do banco SQLite localmente com Drizzle ORM, criando o schema de feedbacks por tenant:

// feedbackObject.ts
import { drizzle } from "drizzle-orm/d1";
import { feedbacks } from "./schema";

export class FeedbackObject {
  constructor(state: DurableObjectState, env: Env) {
    this.state = state;
    this.env = env;
  }

  async fetch(req: Request) {
    const db = drizzle(this.env.DB);
    const { method } = req;

    if (method === "POST") {
      const { message, user } = await req.json();
      await db.insert(feedbacks).values({ message, user });
      return new Response("Feedback recebido!", { status: 201 });
    }

    if (method === "GET") {
      const results = await db.select().from(feedbacks);
      return Response.json(results);
    }

    return new Response("Método não suportado", { status: 405 });
  }
}

🗃️ Schema com Drizzle ORM

Criamos o schema de feedbacks de forma simples:

// schema.ts
import { sqliteTable, text } from "drizzle-orm/sqlite-core";

export const feedbacks = sqliteTable("feedbacks", {
  id: text("id").primaryKey().default(randomUUID()),
  message: text("message").notNull(),
  user: text("user"),
});

Cada instância de DO carrega esse schema de forma isolada.


🧪 Testando: Enviando e Listando Feedbacks

Enviar um feedback:

curl -X POST https://empresaA.superciclo.com   -H "Content-Type: application/json"   -d '{"message": "Adorei a nova interface!", "user": "joao@exemplo.com"}'

Listar feedbacks:

curl https://empresaA.superciclo.com

🚀 Vantagens da Arquitetura por Organização

  • Isolamento Total: cada tenant tem sua base, sem risco de vazar dados entre empresas.
  • Escalabilidade Horizontal: a carga é distribuída por organização.
  • Baixo Acoplamento: evoluir ou debugar uma instância afeta só aquele tenant.

💡 Considerações Finais

Cloudflare Durable Objects + Drizzle ORM oferece uma maneira poderosa e moderna de construir aplicações multi-tenant com isolamento por design.

Esse padrão se encaixa perfeitamente em sistemas onde os dados por organização precisam ser isolados — como um sistema de feedbacks anônimos, onde segurança e separação são essenciais.

Agradecimento especial ao Boris Tane pelo post original que serviu como inspiração para este!


📎 Referência Original

One Database Per User with Cloudflare Durable Objects and Drizzle ORM por Boris Tane


👨‍💻 Construído com:

  • Cloudflare Workers
  • Cloudflare Durable Objects
  • Drizzle ORM (SQLite)
  • Subdomínios para isolamento de tenant

Publicado em 8 de julho de 2025

Mais escritas

Construindo um ciclo rápido de feedback com clientes e devs

8 de jul. de 2025

Superciclo não é só mais uma ferramenta de feedback

6 de jul. de 2025

Desktop App Icon

Experimente o Superciclo hoje com um teste gratuito de 14 dias. Sem necessidade de cartão de crédito.