Cloudflare Workersを軽く使ってみてこれがサーバーレス(ラムダ/FaaS)のスタンダードになってほしいなと思った
#Cloudflare_Workers #サーバーレス #FaaS #ラムダ #lambda #Service_Worker
Cloudflare Workersをほんの少し触ってみた感想。
(サーバーレスのエコシステムなどあんまり深入りしていないので何か変かもしれない)
Cloudflare Workers
Cloudflare WorkersはCloudflareが提供するサーバーレス。FaaSとかラムダとかとも呼ばれると思う。
Service Workerのように書ける
気に入った理由を一言でいえばService Workerのように書けること。
Service WorkerはPWAなどで使われWeb Workerの一種。Web Workerはブラウザの標準にある。標準にあるというのが重要。Service Workerのように書けるため、Service Workerの知識がそのまま使えるところが非常に気に入った。
MDN: Service Worker の使用 - Web API | MDN
以下がCloudflare Workersの例。
code:js
addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request))
})
/**
* Respond to the request
* @param {Request} request
*/
async function handleRequest(request) {
return new Response('hello world', {status: 200})
}
以下は実際にアクセスした様子。
https://gyazo.com/93e1e0f5f622480c70c2832496872599
addEventListener('fetch', ...)やevent.requestなどService Workerでお馴染みの関数やオブジェクトが登場する。
例えばevent.requestの型はReqeust型でService Workerやfetch()のReqeustの知識がそのまま使えた。つまりプロパティやメソッドの名前や使用方法がそのまま使えた。
MDN: Request - Web API | MDN
キャッシュのService Workerと同じように扱えるぽい。
他のサーバーレス系はAPIが独自ぽい
他のサーバーレスのサンプルを見るとだいたい独自ぽいAPI。それが理由でひとつのサーバーレスのサービスに深入りしないようにしていた。
例えば、以下はAWS Lambda、Vercel、Netlify Lambdaの例。
code:js
// AWS Lambda
exports.handler = async function(event, context) {
console.log("EVENT: \n" + JSON.stringify(event, null, 2))
return context.logStreamName
}
AWS Lambda function handler in Node.js - AWS Lambda
code:js
// Vercelの例(旧: Zeit Now)
import { NowRequest, NowResponse } from '@vercel/node'
export default (req: NowRequest, res: NowResponse) => {
res.json({ name: 'John', email: 'john@example.com' })
}
Serverless Functions - Vercel Documentation
code:js
// Netlify Lambda
export async function handler(event, context) {
return {
statusCode: 200,
body: JSON.stringify({ message: Hello world ${Math.floor(Math.random() * 10)} })
};
}
netlify/netlify-lambda: Helps building and serving lambda functions locally and in CI environments
独自のデメリットは、
初めてそのサービスで作りたいときにどうすればrequestのヘッダが取れるかやボディが調べたりに時間が取られること。
そしてその知識が他のサーバーレスのサービスに活用できない。
ベンダーロックインされる。(他のサービスへの移行がしづらい)
などがあり避けていた。
これらを同じように扱えるOSSとかありそうだが(どこかでみたような気がする)、ラップというのは凝りたいときに細かな再現できない差みたいなもので苦しめられる経験則があるのでそういうのも避けていた。
そこでCloudflare Workersを少し触れてみてService WorkerのAPIを再現していたのでこれがサーバーレスのスタンダードになってほしいなと思った。
Cloudflare Workersをちょっと試す時
動きをサクッと試すなら「Cloudflare Workers | Cloudflare Workers」のDemoで以下のページできる。
https://gyazo.com/786383bdca88b97160e7f3346864aae3
エディタの補完が充実
例えば以下はrequest.headersが補完されるようす。@param {Request} requestを書いているため型が分かり補完がいい感じに効く。これもWeb WorkerのAPIと一致していて、既存のService WorkerのTypeScriptの型定義が使えるからだと思う。
https://gyazo.com/8712bf498806ed3ca3f0f5c43f163546
本格的に開発したくなればブラウザは使わなくなりそうだが、そのときはCLIからでもデプロイできる様子。
Quick Start | Cloudflare Workers
Template Gallery | Cloudflare Workersを見ると、JavaScript以外に以下の言語に対応している様子。
TypeScript
COBOL
Rust
Reason
Python
Dart
Scala
Kotlin
透過プロキシぽいものを作る
例えば以下ならfetch(request)するので何もしないWorkerが作れる。
code:js
addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request))
})
async function handleRequest(request) {
const response = await fetch(request)
return response
}
以下のようにfetch()の前後に何か書けば透過的な処理ができる。
code:js
addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request))
})
async function handleRequest(request) {
// ...(リクエスト前に何かする)...
const response = await fetch(request)
// ...(リクエスト後に何かする)...
return response
}
Cloudflareのダッシュボードだと以下のWorkersアイコン。
https://gyazo.com/1a98f7d5599c7ffc9029f12511e6a4f1
以下のようなエディタでブラウザ上で開発できる。
https://gyazo.com/e5da4f138b3cbe1d48f718f8cb6c0145
CloudflareでDNS管理している既存のWebサイトにこのWorkerを設置することができる。
無料プラン
1 日あたり 100,000 件のリクエスト を含む (UTC+0)1
リクエストごとに最大 10ms の CPU 時間
最初のリクエスト後の最小遅延
最大 30 Workers
https://gyazo.com/00b9ac28b9bcf82d89aadb3f763d275b
(リンクを載せたいがダッシュボードのリンク)
自動で課金されたりはしなさそう。Cloudflareの他のサービスに課金しているが「現在のプラン」として無料プランになっていて、Unlimitedプランにするためには「購入ボタン」を押さないといけないようになっていたので安心できそう。
上記画像とは異なるが価格や制限に関する内容は「Limits | Cloudflare Workers」にある。