Cloudflare Workersを軽く使ってみてこれがサーバーレス(ラムダ/FaaS)のスタンダードになってほしいなと思った
(サーバーレスのエコシステムなどあんまり深入りしていないので何か変かもしれない)
Cloudflare Workers
Service Workerのように書ける
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の知識がそのまま使えた。つまりプロパティやメソッドの名前や使用方法がそのまま使えた。 他のサーバーレス系はAPIが独自ぽい
他のサーバーレスのサンプルを見るとだいたい独自ぽいAPI。それが理由でひとつのサーバーレスのサービスに深入りしないようにしていた。
code:js
// AWS Lambda
exports.handler = async function(event, context) {
console.log("EVENT: \n" + JSON.stringify(event, null, 2))
return context.logStreamName
}
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' })
}
code:js
// Netlify Lambda
export async function handler(event, context) {
return {
statusCode: 200,
body: JSON.stringify({ message: Hello world ${Math.floor(Math.random() * 10)} })
};
}
独自のデメリットは、
初めてそのサービスで作りたいときにどうすればrequestのヘッダが取れるかやボディが調べたりに時間が取られること。
そしてその知識が他のサーバーレスのサービスに活用できない。
ベンダーロックインされる。(他のサービスへの移行がしづらい)
などがあり避けていた。
これらを同じように扱えるOSSとかありそうだが(どこかでみたような気がする)、ラップというのは凝りたいときに細かな再現できない差みたいなもので苦しめられる経験則があるのでそういうのも避けていた。
Cloudflare Workersをちょっと試す時
https://gyazo.com/786383bdca88b97160e7f3346864aae3
エディタの補完が充実
例えば以下はrequest.headersが補完されるようす。@param {Request} requestを書いているため型が分かり補完がいい感じに効く。これもWeb WorkerのAPIと一致していて、既存のService WorkerのTypeScriptの型定義が使えるからだと思う。 https://gyazo.com/8712bf498806ed3ca3f0f5c43f163546
本格的に開発したくなればブラウザは使わなくなりそうだが、そのときはCLIからでもデプロイできる様子。
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
}
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プランにするためには「購入ボタン」を押さないといけないようになっていたので安心できそう。