syumai/workers + D1 + sqlc で作る workers
タイトルの構成で、Cloudflare Workers API を作りたい。
あとから見返すようでメモる。
とりあえず syumai/workers の Quick Start の通りにやっていく
❯ wrangler generate my-app syumai/workers/_templates/cloudflare/worker-tinygo
⛅️ wrangler 3.0.1
------------------
▲ [WARNING] The `generate` command is no longer supported and will be removed in a future version.
Creating a worker in my-app from syumai/workers/_templates/cloudflare/worker-tinygo
✨ Success!
generate 消さるのか。どうなるんだろう。なんか代替あるのかなと思って調べたけど特に出てこなかった。気が向いたらあとでちゃんと調べる。
make dev したら Error: write EPIPE
が発生した。
❯ make dev
wrangler dev
⛅️ wrangler 3.0.1
------------------
wrangler dev now uses local mode by default, powered by 🔥 Miniflare and 👷 workerd.
To run an edge preview session for your Worker, use wrangler dev --remote
Running custom build: make build
make[1]: Entering directory '/home/zztkm/dev/github.com/pistachiostudio/hello-api'
go run github.com/syumai/workers/cmd/workers-assets-gen@latest
tinygo build -o ./build/app.wasm -target wasm ./...
make[1]: Leaving directory '/home/zztkm/dev/github.com/pistachiostudio/hello-api'
⎔ Starting local server...
╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ [b] open a browser, [d] open Devtools, [l] turn off local mode, [c] clear console, [x] to exit │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
/usr/local/lib/node_modules/wrangler/wrangler-dist/cli.js:30632
throw a;
^
Error: write EPIPE
at afterWriteDispatched (node:internal/stream_base_commons:160:15)
at writeGeneric (node:internal/stream_base_commons:151:3)
at Socket._writeGeneric (node:net:917:11)
at Socket._write (node:net:929:8)
at writeOrBuffer (node:internal/streams/writable:392:12)
at _write (node:internal/streams/writable:333:10)
at Writable.write (node:internal/streams/writable:337:10)
at Runtime.updateConfig (/usr/local/lib/node_modules/wrangler/node_modules/miniflare/dist/src/index.js:5120:26)
at async #assembleAndUpdateConfig (/usr/local/lib/node_modules/wrangler/node_modules/miniflare/dist/src/index.js:9130:23)
at async #init (/usr/local/lib/node_modules/wrangler/node_modules/miniflare/dist/src/index.js:8894:5)
Emitted 'error' event on Socket instance at:
at emitErrorNT (node:internal/streams/destroy:151:8)
at emitErrorCloseNT (node:internal/streams/destroy:116:3)
at process.processTicksAndRejections (node:internal/process/task_queues:82:21) {
errno: -32,
code: 'EPIPE',
syscall: 'write'
}
Node.js v18.12.1
make: *** [Makefile:3: dev] Error 7
解決方法は issue として残させてもらってるのでそちらを参照
解決策を実施して make dev を実行したら成功した。
http://localhost:8787/hello でアクセスできる。
今回作成する api は json を受け付けて、json を返すようなものにする予定なので、同様のことをやっている例を真似していく。
easyjson を利用するのは、encoding/json が TinyGo 0.27 で使えないから。
TinyGo 0.28 では使えるようになるらしい!
ちょっと目的ははずれるが、せっかく dev 版で、encoding/json が使えるなら試してみたい。
この記事を参考にする。
ビルドするのが面倒なので、PR 内で作成されたバイナリを使う方法でいく。
ChatGPT3.5 に GitHub CLI で Actions Artifacts から zip をダウンロードする方法を聞いた。
↓次のやつが回答。
GitHub CLI(gh)を使用して、任意のリポジトリのGitHub ActionsのartifactsからZIPファイルをダウンロードする方法は次の通りです。
-
最初に、GitHub CLI(gh)をインストールしてセットアップします。GitHub CLIのインストール手順は公式のドキュメントを参照してください。
-
ターミナルまたはコマンドプロンプトを開き、次のコマンドを使用してGitHub CLIにログインします。必要な認証情報を入力します。
gh auth login
-
ダウンロードしたいリポジトリに移動します。例えば、
owner/repository
の形式でリポジトリを指定します。gh repo clone owner/repository cd repository
-
次に、ダウンロードしたいGitHub Actionsのartifactを特定します。まず、利用可能なartifactのリストを表示するために次のコマンドを使用します。
gh run list
リストから、ダウンロードしたいartifactのIDを特定します。
-
次に、次のコマンドを使用してartifactをダウンロードします。
<artifact-id>
の部分には、前の手順で特定したartifactのIDを入力します。gh run download <artifact-id>
コマンドを実行すると、ZIPファイルがカレントディレクトリにダウンロードされます。
これで、GitHub CLIを使用して任意のリポジトリのGitHub ActionsのartifactsからZIPファイルをダウンロードすることができます。必要に応じて、ダウンロードしたZIPファイルを展開して利用できます。
自分がほしいやつはWebUIですでに決まっていて以下のURLの末尾がIDになる。
gh run download 5055378092 --repo tinygo-org/tinygo
結構時間かかったけどDLできた。
DLできたら以下のようにインストールする。
❯ cd linux-amd64-double-zipped/
❯ sudo dpkg -i tinygo_amd64.deb
[sudo] password for zztkm:
(Reading database ... 49896 files and directories currently installed.)
Preparing to unpack tinygo_amd64.deb ...
Unpacking tinygo (0.28.0-dev) over (0.27.0) ...
Setting up tinygo (0.28.0-dev) ...
❯ tinygo version
tinygo version 0.28.0-dev-f366cd5 linux/amd64 (using go version go1.20 and LLVM version 15.0.0)
OK !さっそく encoding/json を試してみる
TinyGo 0.28.0-dev と以下のコードで動いた!
package main
import (
"encoding/json"
"fmt"
"net/http"
"os"
"github.com/syumai/workers"
)
type HelloRequest struct {
Name string `json:"name"`
}
type HelloResponse struct {
Message string `json:"message"`
}
func HelloHandler(w http.ResponseWriter, req *http.Request) {
if req.Method != http.MethodPost {
w.WriteHeader(http.StatusBadRequest)
w.Header().Set("Content-Type", "text/plain")
w.Write([]byte(fmt.Sprintf("request format is invalid: %s", req.Method)))
return
}
var helloReq HelloRequest
if err := json.NewDecoder(req.Body).Decode(&helloReq); err != nil {
w.WriteHeader(http.StatusBadRequest)
w.Header().Set("Content-Type", "text/plain")
w.Write([]byte("request format is invalid"))
return
}
w.Header().Set("Content-Type", "application/json")
msg := fmt.Sprintf("Hello, %s!", helloReq.Name)
helloRes := HelloResponse{Message: msg}
if err := json.NewEncoder(w).Encode(helloRes); err != nil {
fmt.Fprintf(os.Stderr, "failed to encode response: %w\n", err)
}
}
func main() {
http.HandleFunc("/hello", HelloHandler)
workers.Serve(nil) // use http.DefaultServeMux
}
開発サーバーを起動してみる。無事に起動したのでビルドも無事に通ったっぽい。
❯ make dev
wrangler dev
⛅️ wrangler 3.0.1
------------------
wrangler dev now uses local mode by default, powered by 🔥 Miniflare and 👷 workerd.
To run an edge preview session for your Worker, use wrangler dev --remote
Running custom build: make build
tinygo build -o ./build/app.wasm -target wasm ./...
⎔ Starting local server...
ローカルのAPIを叩いてみる
❯ curl --request POST 'http://127.0.0.1:8787/hello' --header 'Content-Type: application/json' --data-raw '{
"name": "zztkm"
}'
{"message":"Hello, zztkm!"}
無事に実行できた!
memo: この時点での app.wasm のサイズは 1.9M
なんか適当な Router を試してみるのもありかもなー。とりあえず今は考えないがあとでやるかも。
次は sqlc で d1 周りのコードを書いていく。
マイグレーションは面倒そうなので、一旦後回しにして、最低限 sqlc が使えるようにする。
頓挫えもんしてるのでどっかで続きやりたい。。。
ただ、sqlc-gen-ts-d1 が思ったより体験良くてモチベあがんねーな
slqc d1 再挑戦したら簡単に作れた。