### Initialize Go Project and Start Dev Server Source: https://github.com/syumai/workers/blob/main/_templates/cloudflare/worker-go/README.md Navigate to the project directory, initialize Go modules, tidy dependencies, and start the development server. Test with a curl request. ```bash cd my-app go mod init go mod tidy npm start curl http://localhost:8787/hello ``` -------------------------------- ### Initialize Go Project and Start Dev Server Source: https://github.com/syumai/workers/blob/main/_templates/browser/browser-go/README.md After creating the project, navigate to the directory, initialize the Go module, tidy dependencies, and start the development server. ```bash cd my-app go mod init go mod tidy npm start ``` -------------------------------- ### Start Development Server Source: https://github.com/syumai/workers/blob/main/README.md Run `npm start` to launch the local development server for your Cloudflare Worker. ```bash npm start ``` -------------------------------- ### Install gonew Command Source: https://github.com/syumai/workers/blob/main/_templates/cloudflare/cron-tinygo/README.md Install the gonew command, which is required to create a new project using this template. ```console go install golang.org/x/tools/cmd/gonew@latest ``` -------------------------------- ### Run Benchmark with Hey Source: https://github.com/syumai/workers/wiki/Benchmark Execute the 'hey' benchmark tool against the deployed 'hello' example URL. This provides performance metrics for the service under test. ```bash ~ hey https://hello.syumai.workers.dev/ Summary: Total: 0.2415 secs Slowest: 0.1540 secs Fastest: 0.0142 secs Average: 0.0464 secs Requests/sec: 828.0532 Response time histogram: 0.014 [1] |■ 0.028 [72] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 0.042 [68] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 0.056 [7] |■■■■ 0.070 [3] |■■ 0.084 [8] |■■■■ 0.098 [17] |■■■■■■■■■ 0.112 [8] |■■■■ 0.126 [14] |■■■■■■■■ 0.140 [0] | 0.154 [2] |■ Latency distribution: 10% in 0.0179 secs 25% in 0.0243 secs 50% in 0.0314 secs 75% in 0.0666 secs 90% in 0.1085 secs 95% in 0.1142 secs 99% in 0.1539 secs Details (average, fastest, slowest): DNS+dialup: 0.0125 secs, 0.0142 secs, 0.1540 secs DNS-lookup: 0.0004 secs, 0.0000 secs, 0.0025 secs req write: 0.0000 secs, 0.0000 secs, 0.0004 secs resp wait: 0.0297 secs, 0.0142 secs, 0.0947 secs resp read: 0.0020 secs, 0.0000 secs, 0.0213 secs Status code distribution: [200] 200 responses ``` -------------------------------- ### Example JSON Response from Server Source: https://github.com/syumai/workers/blob/main/_examples/simple-json-server/README.md Shows the expected JSON response when a valid POST request is made to the /hello endpoint. ```json { "message": "Hello, syumai!" } ``` -------------------------------- ### TinyGo Worker Development Commands Source: https://github.com/syumai/workers/blob/main/_templates/cloudflare/worker-tinygo/README.md These commands are used for developing and deploying your Cloudflare Worker. `npm start` or `go run .` starts the dev server, `npm run build` compiles the Wasm binary, and `npm run deploy` deploys the worker. ```bash npm start # or go run . # or npm run build # or npm run deploy ``` -------------------------------- ### Install workers Package Source: https://github.com/syumai/workers/blob/main/README.md Use `go get` to add the workers package to your Go project dependencies. ```bash go get github.com/syumai/workers ``` -------------------------------- ### Example POST Request to JSON Server Source: https://github.com/syumai/workers/blob/main/_examples/simple-json-server/README.md Demonstrates how to send a POST request with a JSON payload to the /hello endpoint of the simple JSON server. ```curl curl --location --request POST 'https://simple-json-server.syumai.workers.dev/hello' \ --header 'Content-Type: application/json' \ --data-raw '{ "name": "syumai" }' ``` -------------------------------- ### Configure Routes in wrangler.toml Source: https://github.com/syumai/workers/blob/main/_examples/fetch-event/README.md Configure routes in wrangler.toml to trigger a worker for specific domain patterns. This setup is necessary for the example worker to be invoked. ```toml routes = [ { pattern = "sub.example.com/*", zone_name = "example.com" } ] ``` -------------------------------- ### Fetch Durable Object Stub with Go Source: https://context7.com/syumai/workers/llms.txt Obtains a Durable Object stub by name and forwards HTTP requests to it. The binding and class name must be configured in `wrangler.toml`. This example demonstrates getting a consistent stub by name and forwarding an HTTP GET request. ```go package main import ( "fmt" "io" "net/http" "github.com/syumai/workers" "github.com/syumai/workers/cloudflare" ) // wrangler.toml: // [[durable_objects.bindings]] // name = "COUNTER" // class_name = "Counter" func main() { workers.Serve(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { ns, err := cloudflare.NewDurableObjectNamespace("COUNTER") if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } // Get a consistent stub by name — same name always routes to same object id := ns.IdFromName("global-counter") stub, err := ns.Get(id) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } // Forward the request to the Durable Object's fetch() handler if req.Method == http.MethodGet { req.Body = nil } res, err := stub.Fetch(req) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } count, _ := io.ReadAll(res.Body) fmt.Fprintf(w, "counter value: %s", count) })) } ``` -------------------------------- ### Development Commands for Hello Worker Source: https://github.com/syumai/workers/blob/main/_examples/hello/README.md These commands are used for local development, building, and deploying the Cloudflare Worker. Ensure you have wrangler and Go installed. ```bash make dev # run dev server make build # build Go Wasm binary make deploy # deploy worker ``` -------------------------------- ### Test TinyGo Worker Dev Server with Curl Source: https://github.com/syumai/workers/blob/main/_templates/cloudflare/worker-tinygo/README.md Send HTTP requests to the development server using curl to test its functionality. This example shows a GET request to `/hello`. ```bash $ curl http://localhost:8787/hello Hello! ``` -------------------------------- ### Development Commands Source: https://github.com/syumai/workers/blob/main/_examples/basic-auth-proxy/README.md These commands are used for local development and deployment of the worker. Ensure you have Go 1.24.0+ and wrangler installed. ```bash make dev # run dev server make build # build Go Wasm binary make deploy # deploy worker ``` -------------------------------- ### Development Commands Source: https://github.com/syumai/workers/blob/main/_templates/cloudflare/pages-tinygo/README.md Common commands for developing Cloudflare Workers with TinyGo, including starting a dev server, building the Wasm binary, and deploying. ```bash make dev make build make deploy ``` -------------------------------- ### Development Commands for KV Counter Source: https://github.com/syumai/workers/blob/main/_examples/kv-counter/README.md These commands are used for local development, building, and deploying the Cloudflare Worker. Ensure you have Go and wrangler installed. ```bash make dev # run dev server make build # build Go Wasm binary make create-kv-namespace # creates a kv namespace - add binding to wrangler.toml before deploy make deploy # deploy worker ``` -------------------------------- ### Scaffold a New Go Worker Project Source: https://context7.com/syumai/workers/llms.txt Use npm to create a new Cloudflare worker project with the Go template. Navigate into the project directory, initialize Go modules, tidy dependencies, and start the development server. ```bash npm create cloudflare@latest -- --template github.com/syumai/workers/_templates/cloudflare/worker-go cd my-app go mod init go mod tidy npm start # curl http://localhost:8787/hello → "Hello!" ``` -------------------------------- ### List Blog Posts with cURL Source: https://github.com/syumai/workers/blob/main/_examples/d1-blog-server/README.md Use this cURL command to retrieve a list of all blog posts by sending a GET request to the /articles endpoint. ```bash $ curl 'https://d1-blog-server.syumai.workers.dev/articles' ``` ```json { "articles": [ { "id": "bea6cd80-5a83-45f0-b061-0e13a2ad5fba", "title": "example post 2", "body": "body of the example post 2", "createdAt": 1677383758 }, { "id": "f9e8119e-881e-4dc5-9307-af4f2dc79891", "title": "example post", "body": "body of the example post", "createdAt": 1677382874 } ] } ``` -------------------------------- ### Cloudflare Worker Go Development Commands Source: https://github.com/syumai/workers/blob/main/_templates/cloudflare/worker-go/README.md Common commands for developing a Cloudflare Worker with Go, including starting the dev server, building the Wasm binary, and deploying. ```bash npm start # or go run . npm run build npm run deploy ``` -------------------------------- ### Go Middleware for Hono.js Source: https://context7.com/syumai/workers/llms.txt Allows Go middleware to integrate with a Hono JavaScript application. The `Context` provides access to Hono's request context and response helpers. This example chains two middleware: `logging` and `auth`. ```go package main import ( "fmt" "github.com/syumai/workers/exp/hono" ) // Used when the entry point is a Hono app in JS and Go provides middleware func main() { auth := func(c *hono.Context, next func()) { token := c.Req().Get("authorization") if token != "Bearer secret" { c.SetStatus(401) c.Text("unauthorized") return } next() } logging := func(c *hono.Context, next func()) { fmt.Println("request received") next() fmt.Println("response sent") } hono.ServeMiddleware(hono.ChainMiddlewares(logging, auth)) } ``` -------------------------------- ### R2 Object Storage (`cloudflare/r2` package) Source: https://context7.com/syumai/workers/llms.txt Full object storage operations: Head, Get, Put (with HTTP/custom metadata), Delete, List. The binding name must match `r2_buckets[].binding` in `wrangler.toml`. ```APIDOC ## R2 Object Storage (`cloudflare/r2` package) ### `r2.NewBucket` / `Bucket` — Cloudflare R2 Full object storage operations: Head, Get, Put (with HTTP/custom metadata), Delete, List. The binding name must match `r2_buckets[].binding` in `wrangler.toml`. ```go package main import ( "fmt" "io" "net/http" "strings" "github.com/syumai/workers" "github.com/syumai/workers/cloudflare/r2" ) // wrangler.toml: // [[r2_buckets]] // binding = "BUCKET" // bucket_name = "my-bucket" func main() { workers.Serve(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { bucket, err := r2.NewBucket("BUCKET") if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } key := strings.TrimPrefix(req.URL.Path, "/") switch req.Method { case http.MethodGet: obj, err := bucket.Get(key) // returns nil if not found if err != nil || obj == nil { http.NotFound(w, req) return } w.Header().Set("Content-Type", obj.HTTPMetadata.ContentType) w.Header().Set("ETag", obj.HTTPETag) io.Copy(w, obj.Body) case http.MethodPut: _, err := bucket.Put(key, req.Body, &r2.PutOptions{ HTTPMetadata: r2.HTTPMetadata{ContentType: req.Header.Get("Content-Type")}, CustomMetadata: map[string]string{"uploader": "worker"}, }) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } w.WriteHeader(http.StatusCreated) case http.MethodDelete: if err := bucket.Delete(key); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } fmt.Fprintln(w, "deleted") case http.MethodHead: obj, _ := bucket.Head(key) // Body is always nil for Head if obj == nil { http.NotFound(w, req) return } w.Header().Set("ETag", obj.ETag) fmt.Fprintf(w, "size=%d uploaded=%s\n", obj.Size, obj.Uploaded) default: // List all objects objects, err := bucket.List() if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } for _, o := range objects.Objects { fmt.Fprintf(w, "%s (%d bytes)\n", o.Key, o.Size) } } })) } ``` ``` -------------------------------- ### Cloudflare R2 Object Storage with Go Source: https://context7.com/syumai/workers/llms.txt Provides full object storage operations: Head, Get, Put (with HTTP/custom metadata), Delete, List. The binding name must match `r2_buckets[].binding` in `wrangler.toml`. ```go package main import ( "fmt" "io" "net/http" "strings" "github.com/syumai/workers" "github.com/syumai/workers/cloudflare/r2" ) // wrangler.toml: // [[r2_buckets]] // binding = "BUCKET" // bucket_name = "my-bucket" func main() { workers.Serve(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { bucket, err := r2.NewBucket("BUCKET") if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } key := strings.TrimPrefix(req.URL.Path, "/") switch req.Method { case http.MethodGet: obj, err := bucket.Get(key) // returns nil if not found if err != nil || obj == nil { http.NotFound(w, req) return } w.Header().Set("Content-Type", obj.HTTPMetadata.ContentType) w.Header().Set("ETag", obj.HTTPETag) io.Copy(w, obj.Body) case http.MethodPut: _, err := bucket.Put(key, req.Body, &r2.PutOptions{ HTTPMetadata: r2.HTTPMetadata{ContentType: req.Header.Get("Content-Type")}, CustomMetadata: map[string]string{"uploader": "worker"}, }) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } w.WriteHeader(http.StatusCreated) case http.MethodDelete: if err := bucket.Delete(key); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } fmt.Fprintln(w, "deleted") case http.MethodHead: obj, _ := bucket.Head(key) // Body is always nil for Head if obj == nil { http.NotFound(w, req) return } w.Header().Set("ETag", obj.ETag) fmt.Fprintf(w, "size=%d uploaded=%s\n", obj.Size, obj.Uploaded) default: // List all objects objects, err := bucket.List() if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } for _, o := range objects.Objects { fmt.Fprintf(w, "%s (%d bytes)\n", o.Key, o.Size) } } })) } ``` -------------------------------- ### Initialize Go Modules Source: https://github.com/syumai/workers/blob/main/README.md After creating the project, navigate to the directory and run `go mod init` and `go mod tidy` to set up Go modules. ```bash cd my-app go mod init go mod tidy ``` -------------------------------- ### Run Dev Server with Make Source: https://github.com/syumai/workers/blob/main/_examples/fetch/README.md Use this command to run the development server. ```bash make dev ``` -------------------------------- ### Build, Develop, and Deploy Commands Source: https://github.com/syumai/workers/blob/main/_examples/pages-functions/README.md Standard make commands for building the Go Wasm binary, running the development server, and deploying the worker. ```bash make build # build Go Wasm binary ``` ```bash make dev # run dev server ``` ```bash make deploy # deploy worker ``` -------------------------------- ### Development Commands Source: https://github.com/syumai/workers/blob/main/_examples/browser/README.md Commands for local development, building, and deploying the Go WebAssembly application. ```bash make dev # run dev server make build # build Go Wasm binary make deploy # deploy static assets ``` -------------------------------- ### Build and Deploy Worker with Service Bindings Source: https://github.com/syumai/workers/blob/main/_examples/service-bindings/README.md Use make commands to build the Go Wasm binary and deploy the worker after configuring service bindings. ```bash make build # build Go Wasm binary make deploy # deploy worker ``` -------------------------------- ### Get Image Source: https://github.com/syumai/workers/blob/main/_examples/r2-image-server/README.md Retrieves an image object from R2 using its key. ```APIDOC ## GET /{key} ### Description Get an image object at the `key` and returns it. ### Method GET ### Endpoint `/{key}` ### Parameters #### Path Parameters - **key** (string) - Required - The key of the image object to retrieve. ``` -------------------------------- ### Build Go Wasm Binary with Make Source: https://github.com/syumai/workers/blob/main/_examples/fetch/README.md Use this command to build the Go Wasm binary. ```bash make build ``` -------------------------------- ### Run Development Server Source: https://github.com/syumai/workers/blob/main/_examples/sockets/README.md Use this command to run the development server. ```shell make dev # run dev server ``` -------------------------------- ### Development and Build Commands Source: https://github.com/syumai/workers/blob/main/_examples/d1-blog-server/README.md These make commands are used for local development, including initializing the database, running a development server, and building the Go Wasm binary. ```bash # development make init-db-local # initialize local DB (remove all rows) make dev # run dev server make build # build Go Wasm binary ``` -------------------------------- ### Production Deployment Commands Source: https://github.com/syumai/workers/blob/main/_examples/d1-blog-server/README.md Commands for deploying the worker to production, including creating the database, initializing it, and deploying the worker. ```bash # production make create-db # create production DB # copy binding to wrangler.toml make init-db # initialize production DB (remove all rows) make deploy # deploy worker ``` -------------------------------- ### Build Go Wasm Binary Source: https://github.com/syumai/workers/blob/main/_examples/sockets/README.md Use this command to build the Go WebAssembly binary. ```shell make build # build Go Wasm binary ``` -------------------------------- ### Deploy Worker with Make Source: https://github.com/syumai/workers/blob/main/_examples/fetch/README.md Use this command to deploy the worker. ```bash make deploy ``` -------------------------------- ### Test Dev Server - Hello Endpoint with Name Parameter Source: https://github.com/syumai/workers/blob/main/_templates/cloudflare/pages-tinygo/README.md Send a request to the /api/hello endpoint with a 'name' query parameter to test personalized greetings. ```bash curl http://localhost:8787/api/hello?name=Example ``` -------------------------------- ### Create New Project with Template Source: https://github.com/syumai/workers/blob/main/_templates/cloudflare/cron-tinygo/README.md Create a new Cloudflare Worker project using the cron-go template. Replace 'your.module/my-app' with your desired module path. ```console gonew github.com/syumai/workers/_templates/cloudflare/cron-go your.module/my-app # e.g. github.com/syumai/my-app cd my-app go mod tidy make dev # start running dev server ``` -------------------------------- ### Test Dev Server - Hello Endpoint Source: https://github.com/syumai/workers/blob/main/_templates/cloudflare/pages-tinygo/README.md Send a request to the /api/hello endpoint on the development server to test the default greeting. ```bash curl http://localhost:8787/api/hello ``` -------------------------------- ### Non-blocking Lifecycle Control for Workers Source: https://context7.com/syumai/workers/llms.txt Use ServeNonBlock to set the handler without blocking, allowing for additional setup like registering queue consumers before calling Ready(). Done() returns a channel closed when the request completes. ```go package main import ( "net/http" "github.com/syumai/workers" "github.com/syumai/workers/cloudflare/queues" ) func main() { // Register queue consumer before HTTP handler queues.ConsumeNonBlock(func(batch *queues.MessageBatch) error { batch.AckAll() return nil }) // Register HTTP handler without blocking workers.ServeNonBlock(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("ok")) })) // Signal ready, then wait workers.Ready() <-workers.Done() } ``` -------------------------------- ### Development Commands for R2 Image Server Source: https://github.com/syumai/workers/blob/main/_examples/r2-image-server/README.md Common commands for managing the R2 image server development lifecycle, including running a dev server, building the Go Wasm binary, creating an R2 bucket, and deploying the worker. ```bash make dev # run dev server make build # build Go Wasm binary make create-bucket # create r2 bucket make deploy # deploy worker ``` -------------------------------- ### Create Cloudflare Worker Project with TinyGo Template Source: https://github.com/syumai/workers/blob/main/_templates/cloudflare/worker-tinygo/README.md Use this command to create a new worker project using the specified template. ```bash npm create cloudflare@latest -- --template github.com/syumai/workers/_templates/cloudflare/worker-tinygo ``` -------------------------------- ### Create New Project with Pages TinyGo Template Source: https://github.com/syumai/workers/blob/main/_templates/cloudflare/pages-tinygo/README.md Create a new Cloudflare Pages project using the tinygo template. Replace 'your.module/my-app' with your desired module path. ```bash gonew github.com/syumai/workers/_templates/cloudflare/pages-tinygo your.module/my-app cd my-app go mod tidy make build make dev curl http://localhost:8787/api/hello ``` -------------------------------- ### workers.ServeNonBlock, workers.Ready, workers.Done Source: https://context7.com/syumai/workers/llms.txt Provides non-blocking lifecycle control for workers. ServeNonBlock sets the handler without blocking, Ready signals the JS runtime to start processing requests, and Done returns a channel that closes when the request completes. ```APIDOC ## workers.ServeNonBlock / workers.Ready / workers.Done ### Description Provides non-blocking lifecycle control for workers. `ServeNonBlock` sets the handler without blocking, allowing additional setup before signaling readiness. `Ready()` signals the JS runtime to start processing requests, and `Done()` returns a channel closed when the request completes. ### Method `workers.ServeNonBlock(handler http.Handler)` `workers.Ready()` `<-workers.Done()` ### Parameters * **handler** (*http.Handler) - The HTTP handler to serve (for `ServeNonBlock`). ### Request Example ```go package main import ( "net/http" "github.com/syumai/workers" "github.com/syumai/workers/cloudflare/queues" ) func main() { // Register queue consumer before HTTP handler queues.ConsumeNonBlock(func(batch *queues.MessageBatch) error { batch.AckAll() return nil }) // Register HTTP handler without blocking workers.ServeNonBlock(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("ok")) })) // Signal ready, then wait workers.Ready() <-workers.Done() } ``` ### Response `workers.Done()` returns a channel that is closed when the request completes. ``` -------------------------------- ### Create Cloudflare Worker Project with Browser Go Template Source: https://github.com/syumai/workers/blob/main/_templates/browser/browser-go/README.md Use this command to create a new worker project based on the browser-go template. ```bash npm create cloudflare@latest -- --template github.com/syumai/workers/_templates/browser/browser-go ``` -------------------------------- ### Development Commands Source: https://github.com/syumai/workers/blob/main/_examples/mysql-blog-server/README.md These make commands are used for local development, building the Go Wasm binary, and deploying the worker. ```makefile make dev # run dev server make build # build Go Wasm binary make deploy # deploy worker ``` -------------------------------- ### Development Commands for Browser Go Project Source: https://github.com/syumai/workers/blob/main/_templates/browser/browser-go/README.md These commands are used for managing the development and deployment of your browser-based Go application. ```bash npm start # run dev server npm run build # build Go Wasm binary npm run deploy # deploy static assets ``` -------------------------------- ### Create Cloudflare Worker Project Source: https://github.com/syumai/workers/blob/main/README.md Use `npm create cloudflare` with the provided template to scaffold a new Go worker project. ```bash npm create cloudflare@latest -- --template github.com/syumai/workers/_templates/cloudflare/worker-go ``` -------------------------------- ### Cloudflare D1 via database/sql Source: https://context7.com/syumai/workers/llms.txt Registers a `database/sql`-compatible driver named "d1". Import the package for its side effects to register the driver, then use `sql.Open("d1", bindingName)` for standard Go SQL operations. ```APIDOC ## `d1.OpenConnector` — Cloudflare D1 via `database/sql` Registers a `database/sql`-compatible driver named `"d1"`. Import the package for its side effects to register the driver, then use `sql.Open("d1", bindingName)` for standard Go SQL operations. ### Example Usage ```go package main import ( "database/sql" "log" "net/http" "encoding/json" "github.com/syumai/workers" _ "github.com/syumai/workers/cloudflare/d1" // registers "d1" driver ) // wrangler.toml: // [[d1_databases]] // binding = "DB" // database_name = "my-db" // database_id = "..." type Article struct { ID int `json:"id"` Title string `json:"title"` } func main() { db, err := sql.Open("d1", "DB") if err != nil { log.Fatalf("open DB: %v", err) } http.HandleFunc("/articles", func(w http.ResponseWriter, req *http.Request) { switch req.Method { case http.MethodGet: rows, err := db.QueryContext(req.Context(), "SELECT id, title FROM articles ORDER BY id") if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } defer rows.Close() var articles []Article for rows.Next() { var a Article rows.Scan(&a.ID, &a.Title) articles = append(articles, a) } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(articles) case http.MethodPost: var a Article json.NewDecoder(req.Body).Decode(&a) res, err := db.ExecContext(req.Context(), "INSERT INTO articles (title) VALUES (?)", a.Title) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } id, _ := res.LastInsertId() w.WriteHeader(http.StatusCreated) json.NewEncoder(w).Encode(map[string]int64{"id": id}) } }) workers.Serve(nil) } ``` ``` -------------------------------- ### Cloudflare Cache API with Go Source: https://context7.com/syumai/workers/llms.txt Demonstrates using the Cache API to store and retrieve responses. Cache writes should be done in `cloudflare.WaitUntil` to avoid blocking the response. ```go package main import ( "bytes" "fmt" "io" "net/http" "time" "github.com/syumai/workers" "github.com/syumai/workers/cloudflare" "github.com/syumai/workers/cloudflare/cache" ) func main() { workers.Serve(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { // Use a named cache namespace c := cache.New(cache.WithNamespace("my-cache")) // Try cache hit first cached, err := c.Match(req, &cache.MatchOptions{IgnoreMethod: false}) if err == nil && cached != nil { w.Header().Set("X-Cache", "HIT") io.Copy(w, cached.Body) return } // cache.ErrCacheNotFound when no match // Generate response body := fmt.Sprintf("generated at %d", time.Now().UnixMilli()) w.Header().Set("Cache-Control", "max-age=30") w.Header().Set("X-Cache", "MISS") w.Write([]byte(body)) // Store response in cache asynchronously cloudflare.WaitUntil(func() { resp := &http.Response{ StatusCode: http.StatusOK, Header: w.Header().Clone(), Body: io.NopCloser(bytes.NewBufferString(body)), } if putErr := c.Put(req, resp); putErr != nil { fmt.Println("cache put error:", putErr) } }) })) } ``` -------------------------------- ### Deploy Worker Source: https://github.com/syumai/workers/blob/main/_examples/sockets/README.md Use this command to deploy the worker. ```shell make deploy # deploy worker ``` -------------------------------- ### hono.ServeMiddleware / hono.ChainMiddlewares Source: https://context7.com/syumai/workers/llms.txt Allows writing Go middleware that plugs into a Hono JavaScript application. The `Context` provides access to Hono's request context and response helpers. ```APIDOC ## Experimental Hono Middleware (`exp/hono` package) ### `hono.ServeMiddleware` / `hono.ChainMiddlewares` — Go middleware for Hono.js Allows writing Go middleware that plugs into a [Hono](https://hono.dev/) JavaScript application. The `Context` provides access to Hono's request context and response helpers. ### Example Usage ```go package main import ( "fmt" "github.com/syumai/workers/exp/hono" ) // Used when the entry point is a Hono app in JS and Go provides middleware func main() { auth := func(c *hono.Context, next func()) { token := c.Req().Get("authorization") if token != "Bearer secret" { c.SetStatus(401) c.Text("unauthorized") return } next() } logging := func(c *hono.Context, next func()) { fmt.Println("request received") next() fmt.Println("response sent") } hono.ServeMiddleware(hono.ChainMiddlewares(logging, auth)) } ``` ``` -------------------------------- ### Serve Default ServeMux with workers Source: https://github.com/syumai/workers/blob/main/README.md If `nil` is passed to `workers.Serve()`, it defaults to using `http.DefaultServeMux`. Register handlers using `http.HandleFunc` or `http.Handle`. ```go func main() { http.HandleFunc("/hello", func (w http.ResponseWriter, req *http.Request) { ... }) workers.Serve(nil) // if nil is given, http.DefaultServeMux is used. } ``` -------------------------------- ### Create Blog Post with cURL Source: https://github.com/syumai/workers/blob/main/_examples/d1-blog-server/README.md Use this cURL command to create a new blog post by sending a POST request to the /articles endpoint with JSON data. ```bash $ curl -X POST 'https://d1-blog-server.syumai.workers.dev/articles' \ -H 'Content-Type: application/json' \ -d '{ "title":"example post", "body":"body of the example post" }' ``` ```json { "article": { { "id": "f9e8119e-881e-4dc5-9307-af4f2dc79891", "title": "example post", "body": "body of the example post", "createdAt": 1677382874 } } } ``` -------------------------------- ### Hello Endpoint Source: https://github.com/syumai/workers/blob/main/_templates/cloudflare/pages-tinygo/pages/index.html A simple endpoint to test basic API functionality. ```APIDOC ## GET /api/hello ### Description This endpoint returns a greeting. It can optionally take a 'name' query parameter. ### Method GET ### Endpoint /api/hello ### Parameters #### Query Parameters - **name** (string) - Optional - The name to greet. ### Request Example ```json { "example": "/api/hello?name=Example" } ``` ### Response #### Success Response (200) - **message** (string) - A greeting message. ``` -------------------------------- ### Test Dev Server - Hello2 Endpoint Source: https://github.com/syumai/workers/blob/main/_templates/cloudflare/pages-tinygo/README.md Send a request to the /api/hello2 endpoint on the development server. ```bash curl http://localhost:8787/api/hello2 ``` -------------------------------- ### Hello2 Endpoint Source: https://github.com/syumai/workers/blob/main/_templates/cloudflare/pages-tinygo/pages/index.html Another simple endpoint for testing. ```APIDOC ## GET /api/hello2 ### Description This endpoint provides a basic response. ### Method GET ### Endpoint /api/hello2 ### Response #### Success Response (200) - **message** (string) - A response message. ``` -------------------------------- ### Test Dev Server - Hello3 Endpoint Source: https://github.com/syumai/workers/blob/main/_templates/cloudflare/pages-tinygo/README.md Send a request to the /api/hello3 endpoint on the development server. ```bash curl http://localhost:8787/api/hello3 ``` -------------------------------- ### Cloudflare Queues Producer and Consumer with Go Source: https://context7.com/syumai/workers/llms.txt Implements Cloudflare Queues producer and consumer logic using the workers/cloudflare/queues package. Supports sending various message types and consuming batches with per-message acknowledgments. ```go package main import ( "encoding/json" "log" "net/http" "github.com/syumai/workers" "github.com/syumai/workers/cloudflare/queues" ) // wrangler.toml: // [[queues.producers]] // queue = "my-queue" // binding = "QUEUE" // // [[queues.consumers]] // queue = "my-queue" type Event struct { UserID string `json:"user_id"` Action string `json:"action"` } func main() { // Register consumer (non-blocking because we also have an HTTP handler) queues.ConsumeNonBlock(func(batch *queues.MessageBatch) error { log.Printf("batch from queue: %s, count: %d", batch.Queue, len(batch.Messages)) for _, msg := range batch.Messages { body, err := msg.StringBody() if err != nil { msg.Retry() // re-deliver this specific message continue } log.Printf("message id=%s body=%s attempts=%d", msg.ID, body, msg.Attempts) msg.Ack() } return nil }) http.HandleFunc("/publish", func(w http.ResponseWriter, req *http.Request) { q, err := queues.NewProducer("QUEUE") if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } // Send a single JSON message evt := Event{UserID: "u123", Action: "signup"} if err := q.SendJSON(evt); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } // Send a batch of text messages batch := []*queues.MessageSendRequest{ {Body: json.RawMessage(`"msg-1"`), ContentType: queues.ContentTypeText}, {Body: json.RawMessage(`"msg-2"`), ContentType: queues.ContentTypeText}, } if err := q.SendBatch(batch); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } w.Write([]byte("published\n")) }) workers.Serve(nil) } ``` -------------------------------- ### Create Blog Post Source: https://github.com/syumai/workers/blob/main/_examples/d1-blog-server/README.md Allows users to create a new blog post by sending a POST request with the title and body in the request payload. ```APIDOC ## POST /articles ### Description Creates a new blog post. ### Method POST ### Endpoint /articles ### Request Body - **title** (string) - Required - The title of the blog post. - **body** (string) - Required - The content of the blog post. ### Request Example ```json { "title":"example post", "body":"body of the example post" } ``` ### Response #### Success Response (200) - **article** (object) - Contains the created article details. - **id** (string) - The unique identifier for the article. - **title** (string) - The title of the article. - **body** (string) - The content of the article. - **createdAt** (integer) - The timestamp when the article was created. #### Response Example ```json { "article": { "id": "f9e8119e-881e-4dc5-9307-af4f2dc79891", "title": "example post", "body": "body of the example post", "createdAt": 1677382874 } } ``` ``` -------------------------------- ### Test Dev Server with Simulated Cron Event Source: https://github.com/syumai/workers/blob/main/_templates/cloudflare/cron-tinygo/README.md Simulate a cron event by sending an HTTP POST request to the local development server to test the cron job functionality. ```console curl -X POST http://localhost:8787/cron ``` -------------------------------- ### Serve Custom HTTP Handler with workers Source: https://github.com/syumai/workers/blob/main/README.md Implement an `http.HandlerFunc` and pass it to `workers.Serve()` to run it on Cloudflare Workers. ```go func main() { var handler http.HandlerFunc = func (w http.ResponseWriter, req *http.Request) { ... } workers.Serve(handler) } ``` -------------------------------- ### Hello3 Endpoint Source: https://github.com/syumai/workers/blob/main/_templates/cloudflare/pages-tinygo/pages/index.html A third endpoint for testing. ```APIDOC ## GET /api/hello3 ### Description This endpoint provides a basic response. ### Method GET ### Endpoint /api/hello3 ### Response #### Success Response (200) - **message** (string) - A response message. ``` -------------------------------- ### Supported Commands Source: https://github.com/syumai/workers/blob/main/_examples/queues/README.md These commands are used to manage the development and deployment of the Cloudflare Worker project. ```shell make dev # run dev server make build # build Go Wasm binary make create-queue # creates the queue make deploy # deploy worker ``` -------------------------------- ### List Blog Posts with cURL Source: https://github.com/syumai/workers/blob/main/_examples/mysql-blog-server/README.md Execute this cURL command to retrieve a list of all blog posts from the server. The response will be a JSON object containing an array of articles. ```bash $ curl 'http://localhost:8787/articles' { "articles": [ { "id": "bea6cd80-5a83-45f0-b061-0e13a2ad5fba", "title": "example post 2", "body": "body of the example post 2", "createdAt": 1677383758 }, { "id": "f9e8119e-881e-4dc5-9307-af4f2dc79891", "title": "example post", "body": "body of the example post", "createdAt": 1677382874 } ] } ``` -------------------------------- ### Cloudflare D1 Database Access with Go SQL Driver Source: https://context7.com/syumai/workers/llms.txt Registers and uses the 'd1' driver for Cloudflare D1 databases via Go's standard database/sql package. Requires importing the driver for side effects. Configure bindings in wrangler.toml. ```go package main import ( "database/sql" "log" "net/http" "encoding/json" "github.com/syumai/workers" _ "github.com/syumai/workers/cloudflare/d1" // registers "d1" driver ) // wrangler.toml: // [[d1_databases]] // binding = "DB" // database_name = "my-db" // database_id = "..." type Article struct { ID int `json:"id"` Title string `json:"title"` } func main() { db, err := sql.Open("d1", "DB") if err != nil { log.Fatalf("open DB: %v", err) } http.HandleFunc("/articles", func(w http.ResponseWriter, req *http.Request) { switch req.Method { case http.MethodGet: rows, err := db.QueryContext(req.Context(), "SELECT id, title FROM articles ORDER BY id") if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } defer rows.Close() var articles []Article for rows.Next() { var a Article rows.Scan(&a.ID, &a.Title) articles = append(articles, a) } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(articles) case http.MethodPost: var a Article json.NewDecoder(req.Body).Decode(&a) res, err := db.ExecContext(req.Context(), "INSERT INTO articles (title) VALUES (?)", a.Title) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } id, _ := res.LastInsertId() w.WriteHeader(http.StatusCreated) json.NewEncoder(w).Encode(map[string]int64{"id": id}) } }) workers.Serve(nil) } ``` -------------------------------- ### Test Dev Server with Curl Source: https://github.com/syumai/workers/blob/main/_templates/cloudflare/worker-go/README.md Send HTTP requests to the local development server to test worker functionality. ```bash $ curl http://localhost:8787/hello Hello! ``` ```bash $ curl -X POST -d "test message" http://localhost:8787/echo test message ``` -------------------------------- ### Verify Worker Running Locally Source: https://github.com/syumai/workers/blob/main/README.md Use `curl` to send a request to the local development server and verify the worker is responding. ```bash curl http://localhost:8787/hello ``` -------------------------------- ### KV Storage (`cloudflare/kv` package) Source: https://context7.com/syumai/workers/llms.txt Provides get/put/delete/list operations on a KV namespace. The binding name must match `kv_namespaces[].binding` in `wrangler.toml`. ```APIDOC ## KV Storage (`cloudflare/kv` package) ### `kv.NewNamespace` / `Namespace` — Cloudflare Workers KV Provides get/put/delete/list operations on a KV namespace. The binding name must match `kv_namespaces[].binding` in `wrangler.toml`. ```go package main import ( "fmt" "net/http" "strconv" "github.com/syumai/workers" "github.com/syumai/workers/cloudflare/kv" ) // wrangler.toml: // [[kv_namespaces]] // binding = "COUNTER" // id = "abc123..." func main() { http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) { ns, err := kv.NewNamespace("COUNTER") if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } // Get current value (returns "" if missing) val, err := ns.GetString("count", &kv.GetOptions{CacheTTL: 60}) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } n, _ := strconv.Atoi(val) n++ // Put new value with a 24-hour TTL err = ns.PutString("count", strconv.Itoa(n), &kv.PutOptions{ExpirationTTL: 86400}) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } // List all keys with a prefix result, _ := ns.List(&kv.ListOptions{Prefix: "count", Limit: 10}) for _, k := range result.Keys { fmt.Fprintf(w, "key=%s exp=%d\n", k.Name, k.Expiration) } fmt.Fprintf(w, "count=%d\n", n) }) workers.Serve(nil) } ``` ``` -------------------------------- ### Test TinyGo Worker Dev Server with POST Request Source: https://github.com/syumai/workers/blob/main/_templates/cloudflare/worker-tinygo/README.md Send a POST request with data to the development server using curl to test echo functionality. ```bash $ curl -X POST -d "test message" http://localhost:8787/echo test message ``` -------------------------------- ### Create Image Source: https://github.com/syumai/workers/blob/main/_examples/r2-image-server/README.md Creates or updates an image object in R2 at the specified key. ```APIDOC ## POST /{key} ### Description Create an image object at the `key` and uploads image. ### Method POST ### Endpoint `/{key}` ### Parameters #### Path Parameters - **key** (string) - Required - The key where the image object will be created or updated. #### Request Body - The request body must be binary data representing the image. - The request header must include the `Content-Type` specifying the image format (e.g., `image/jpeg`, `image/png`). ```