Cloudflare bindings
homura-runtime は Workers の binding を Ruby オブジェクトとして扱えるようにします。Sinatra アプリでは d1、kv、bucket、ai、jobs_queue、durable_object などの helper から使うのが基本です。
対応範囲
| Cloudflare 機能 | Ruby 側の入口 | 用途 |
|---|---|---|
| D1 | d1, db, Sequel.connect(adapter: :d1, d1: d1) | SQL database、Sequel dataset、migration |
| KV | kv | session-like state、cache、small JSON documents |
| R2 | bucket | object storage、uploads、binary assets |
| Workers AI | ai.run(model, inputs) | LLM / embedding / image など Workers AI models |
| Queues | jobs_queue, consume_queue | background jobs、DLQ、retry |
| Durable Objects | durable_object(:name, id), Cloudflare::DurableObject.define | per-id state、coordination、WebSocket dispatch |
| Cache API | Cloudflare::Cache.default | edge cache read/write/delete |
| Cron Triggers | schedule '*/5 * * * *' | scheduled jobs |
| Email Routing / Send | send_email / Email Service docs | mail 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 にしてください。