Skip to content

Commit

Permalink
Merge pull request #30 from aki-0421/service-bindings
Browse files Browse the repository at this point in the history
Add service bindings
  • Loading branch information
syumai committed Apr 11, 2023
2 parents 460b011 + 05d3817 commit 7926558
Show file tree
Hide file tree
Showing 10 changed files with 152 additions and 2 deletions.
8 changes: 8 additions & 0 deletions cloudflare/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package cloudflare

import (
"context"
"syscall/js"

"github.com/syumai/workers/cloudflare/internal/cfruntimecontext"
)
Expand All @@ -12,3 +13,10 @@ import (
func Getenv(ctx context.Context, name string) string {
return cfruntimecontext.GetRuntimeContextEnv(ctx).Get(name).String()
}

// GetBinding gets a value of an environment binding.
// - https://developers.cloudflare.com/workers/platform/bindings/about-service-bindings/
// - This function panics when a runtime context is not found.
func GetBinding(ctx context.Context, name string) js.Value {
return cfruntimecontext.GetRuntimeContextEnv(ctx).Get(name)
}
25 changes: 23 additions & 2 deletions cloudflare/fetch/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,30 @@ type Client struct {
namespace js.Value
}

// applyOptions applies client options.
func (c *Client) applyOptions(opts []ClientOption) {
for _, opt := range opts {
opt(c)
}
}

// ClientOption is a type that represents an optional function.
type ClientOption func(*Client)

// WithBinding changes the objects that Fetch API belongs to.
// This is useful for service bindings, mTLS, etc.
func WithBinding(bind js.Value) ClientOption {
return func(c *Client) {
c.namespace = bind
}
}

// NewClient returns new Client
func NewClient() *Client {
return &Client{
func NewClient(opts ...ClientOption) *Client {
c := &Client{
namespace: jsutil.Global,
}
c.applyOptions(opts)

return c
}
1 change: 1 addition & 0 deletions examples/service-bindings/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
dist
12 changes: 12 additions & 0 deletions examples/service-bindings/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.PHONY: dev
dev:
wrangler dev

.PHONY: build
build:
mkdir -p dist
tinygo build -o ./dist/app.wasm -target wasm ./...

.PHONY: publish
publish:
wrangler publish
32 changes: 32 additions & 0 deletions examples/service-bindings/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# service-bindings

- Service bindings are an API that facilitate Worker-to-Worker communication via explicit bindings defined in your configuration.
- In this example, invoke [hello](https://github.com/syumai/workers/tree/main/examples/hello) using Service bindings.

## Development

### Requirements

This project requires these tools to be installed globally.

* wrangler
* tinygo

### Deploy Steps

1. Deploy [hello](https://github.com/syumai/workers/tree/main/examples/hello) first.
2. Define service bindings in `wrangler.toml`.
```toml
services = [
{ binding = "hello", service = "hello" }
]
```
3. Deploy this example.
```
make build # build Go Wasm binary
make publish # publish worker
```

## Documents

- https://developers.cloudflare.com/workers/runtime-apis/service-bindings/
7 changes: 7 additions & 0 deletions examples/service-bindings/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module github.com/syumai/fetch

go 1.18

require github.com/syumai/workers v0.0.0

replace github.com/syumai/workers => ../../
2 changes: 2 additions & 0 deletions examples/service-bindings/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
github.com/syumai/workers v0.1.0 h1:z5QfQR2X+PCKzom7RodpI5J4D5YF7NT7Qwzb9AM9dgY=
github.com/syumai/workers v0.1.0/go.mod h1:alXIDhTyeTwSzh0ZgQ3cb9HQPyyYfIejupE4Z3efr14=
36 changes: 36 additions & 0 deletions examples/service-bindings/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package main

import (
"fmt"
"io"
"net/http"

"github.com/syumai/workers"
"github.com/syumai/workers/cloudflare"
"github.com/syumai/workers/cloudflare/fetch"
)

func main() {
handler := http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
ctx := req.Context()

obj := cloudflare.GetBinding(ctx, "hello")
cli := fetch.NewClient(fetch.WithBinding(obj))
r, err := fetch.NewRequest(ctx, http.MethodGet, req.URL.String(), nil)
if err != nil {
fmt.Println(err)
w.WriteHeader(http.StatusInternalServerError)
return
}

res, err := cli.Do(r)
if err != nil {
fmt.Println(err)
w.WriteHeader(http.StatusInternalServerError)
return
}

io.Copy(w, res.Body)
})
workers.Serve(handler)
}
22 changes: 22 additions & 0 deletions examples/service-bindings/worker.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import "../assets/polyfill_performance.js";
import "../assets/wasm_exec.js";
import mod from "./dist/app.wasm";

const go = new Go();

const readyPromise = new Promise((resolve) => {
globalThis.ready = resolve;
});

const load = WebAssembly.instantiate(mod, go.importObject).then((instance) => {
go.run(instance);
return instance;
});

export default {
async fetch(req, env, ctx) {
await load;
await readyPromise;
return handleRequest(req, { env, ctx });
}
}
9 changes: 9 additions & 0 deletions examples/service-bindings/wrangler.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
name = "service-bindings"
main = "./worker.mjs"
compatibility_date = "2023-02-24"
services = [
{ binding = "hello", service = "hello" }
]

[build]
command = "make build"

0 comments on commit 7926558

Please sign in to comment.