From ca2975fcc234e9197144571d69576b5fccfc720b Mon Sep 17 00:00:00 2001 From: Ikki Nishihara Date: Sun, 11 Oct 2026 17:33:34 +0900 Subject: [PATCH] =?UTF-8?q?docs:=20=E8=A4=87=E6=95=B0=E3=82=B3=E3=83=BC?= =?UTF-8?q?=E3=83=89=E3=83=99=E3=83=BC=E3=82=B9=E3=82=92=E3=83=9B=E3=82=B9?= =?UTF-8?q?=E3=83=88=E3=81=A7=E6=8C=AF=E3=82=8A=E5=88=86=E3=81=91=E3=82=8B?= =?UTF-8?q?=E5=AE=9F=E8=A1=8C=E4=BE=8B=E3=82=92=E8=BF=BD=E5=8A=A0=20#58?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- samples/multiple-codebases/README.md | 45 +++++++++++++++++++++++++ samples/multiple-codebases/app-one.js | 9 +++++ samples/multiple-codebases/app-two.js | 9 +++++ samples/multiple-codebases/config.capnp | 25 ++++++++++++++ samples/multiple-codebases/router.js | 16 +++++++++ 5 files changed, 104 insertions(+) create mode 100644 samples/multiple-codebases/README.md create mode 100644 samples/multiple-codebases/app-one.js create mode 100644 samples/multiple-codebases/app-two.js create mode 100644 samples/multiple-codebases/config.capnp create mode 100644 samples/multiple-codebases/router.js diff --git a/samples/multiple-codebases/README.md b/samples/multiple-codebases/README.md new file mode 100644 index 00000000000..382236467ee --- /dev/null +++ b/samples/multiple-codebases/README.md @@ -0,0 +1,45 @@ +# Multiple Codebases Example + +This example runs two applications with separate Worker scripts in one workerd +process. Both applications share a listening socket. A router Worker selects an +application by the request URL's hostname and forwards the request through a +service binding. Unrecognized hostnames receive a 404 response. + +Use this pattern for codebases you trust, such as multiple applications belonging +to the same organization. Host-based routing does not provide the security +isolation needed to run arbitrary, potentially malicious tenant code. + +## Run + +From this directory, using a workerd binary: + +```sh +workerd serve config.capnp +``` + +Or from the repository root, using Bazel: + +```sh +bazel run //src/workerd/server:workerd -- serve "$PWD/samples/multiple-codebases/config.capnp" +``` + +## Try Both Applications + +The example listens on `127.0.0.1:8080`. Set the `Host` header to select an +application without configuring local DNS: + +```sh +curl -H 'Host: one.example.test' 'http://127.0.0.1:8080/hello?name=one' +# App one: http://one.example.test/hello?name=one + +curl -H 'Host: two.example.test' 'http://127.0.0.1:8080/hello?name=two' +# App two: http://two.example.test/hello?name=two + +curl -i -H 'Host: unknown.example.test' http://127.0.0.1:8080/ +# HTTP/1.1 404 Not Found +``` + +Each application's service can have its own modules, bindings, and compatibility +date. To add an application, configure its service, give the router a binding to +that service, and add its hostname to the router. The original request, including +its path, query string, method, and body, is passed to the selected application. diff --git a/samples/multiple-codebases/app-one.js b/samples/multiple-codebases/app-one.js new file mode 100644 index 00000000000..6d3e6c58b84 --- /dev/null +++ b/samples/multiple-codebases/app-one.js @@ -0,0 +1,9 @@ +// Copyright (c) 2026 Cloudflare, Inc. +// Licensed under the Apache 2.0 license found in the LICENSE file or at: +// https://opensource.org/licenses/Apache-2.0 + +export default { + fetch(request) { + return new Response(`App one: ${request.url}\n`); + }, +}; diff --git a/samples/multiple-codebases/app-two.js b/samples/multiple-codebases/app-two.js new file mode 100644 index 00000000000..e8f106adbe0 --- /dev/null +++ b/samples/multiple-codebases/app-two.js @@ -0,0 +1,9 @@ +// Copyright (c) 2026 Cloudflare, Inc. +// Licensed under the Apache 2.0 license found in the LICENSE file or at: +// https://opensource.org/licenses/Apache-2.0 + +export default { + fetch(request) { + return new Response(`App two: ${request.url}\n`); + }, +}; diff --git a/samples/multiple-codebases/config.capnp b/samples/multiple-codebases/config.capnp new file mode 100644 index 00000000000..fdbf8b0eb4a --- /dev/null +++ b/samples/multiple-codebases/config.capnp @@ -0,0 +1,25 @@ +using Workerd = import "/workerd/workerd.capnp"; + +const multipleCodebasesExample :Workerd.Config = ( + services = [ + (name = "router", worker = ( + modules = [(name = "router", esModule = embed "router.js")], + compatibilityDate = "2023-02-28", + bindings = [ + (name = "APP_ONE", service = "app-one"), + (name = "APP_TWO", service = "app-two"), + ], + )), + (name = "app-one", worker = ( + modules = [(name = "app", esModule = embed "app-one.js")], + compatibilityDate = "2023-02-28", + )), + (name = "app-two", worker = ( + modules = [(name = "app", esModule = embed "app-two.js")], + compatibilityDate = "2023-02-28", + )), + ], + sockets = [ + (name = "http", address = "127.0.0.1:8080", http = (), service = "router"), + ], +); diff --git a/samples/multiple-codebases/router.js b/samples/multiple-codebases/router.js new file mode 100644 index 00000000000..576bee1ce3e --- /dev/null +++ b/samples/multiple-codebases/router.js @@ -0,0 +1,16 @@ +// Copyright (c) 2026 Cloudflare, Inc. +// Licensed under the Apache 2.0 license found in the LICENSE file or at: +// https://opensource.org/licenses/Apache-2.0 + +export default { + fetch(request, env) { + switch (new URL(request.url).hostname) { + case 'one.example.test': + return env.APP_ONE.fetch(request); + case 'two.example.test': + return env.APP_TWO.fetch(request); + default: + return new Response('Unknown host\n', { status: 404 }); + } + }, +};