homura Docs App | Posts About Login
Ctrl+K

Cloudflare bindings

homura-runtime は Workers の binding を Ruby オブジェクトとして扱えるようにします。Sinatra アプリでは d1kvbucketaijobs_queuedurable_object などの helper から使うのが基本です。

対応範囲

Cloudflare 機能Ruby 側の入口用途
D1d1, db, Sequel.connect(adapter: :d1, d1: d1)SQL database、Sequel dataset、migration
KVkvsession-like state、cache、small JSON documents
R2bucketobject storage、uploads、binary assets
Workers AIai.run(model, inputs)LLM / embedding / image など Workers AI models
Queuesjobs_queue, consume_queuebackground jobs、DLQ、retry
Durable Objectsdurable_object(:name, id), Cloudflare::DurableObject.defineper-id state、coordination、WebSocket dispatch
Cache APICloudflare::Cache.defaultedge cache read/write/delete
Cron Triggersschedule '*/5 * * * *'scheduled jobs
Email Routing / Sendsend_email / Email Service docsmail send / debug mail demo

D1

require 'sequel'

get '/posts' do
  db = Sequel.connect(adapter: :d1, d1: d1)
  content_type 'application/json'
  db[:posts].order(Sequel.desc(:id)).all.to_json
end

KV

get '/counter' do
  raw = kv.get('counter')
  count = raw.to_i + 1
  kv.put('counter', count.to_s)
  count.to_s
end

R2

post '/upload' do
  file = params[:file]
  bucket.put("uploads/#{file[:filename]}", file[:tempfile].read)
  redirect to('/uploads'), 303
end

Workers AI

post '/chat' do
  result = ai.run('@cf/google/gemma-4-26b-a4b-it',
                  messages: [{ role: 'user', content: params[:message] }])
  result.to_json
end

Queues

post '/jobs' do
  jobs_queue.send({ kind: 'refresh', id: params[:id] })
  redirect to('/jobs'), 303
end

consume_queue 'jobs' do |batch|
  batch.messages.each do |msg|
    # work...
    msg.ack
  end
end

Durable Objects

Cloudflare::DurableObject.define(:counter) do |request, storage|
  count = storage.get('count').to_i + 1
  storage.put('count', count)
  [200, { 'content-type' => 'text/plain' }, [count.to_s]]
end

get '/counter/:name' do
  durable_object(:counter, params[:name]).get('/').body
end

Cache

cache = Cloudflare::Cache.default
cached = cache.match(request.url)
return cached.body if cached

body = expensive_render
cache.put(request.url, [200, { 'cache-control' => 'max-age=60' }, [body]])
body

production safety

公開 demo route は HOMURA_ENABLE_*_DEMOS のような env flag で無効化できます。binding が存在しない環境では helper が nil を返すか、明示的な binding error を出すため、production では wrangler.toml と secret / binding 設定を source of truth にしてください。