Ergonomic Service Bindings for Cloudflare Workers: no more HTTP calls—directly call functions from your other workers
Service Bindings let your different Cloudflare workers talk to each other, quickly. However, it requires sending a mock HTTP request to the worker with which you're trying to communicate—which gives a lot of flexibility, but is sometimes more overhead than needed. This library simplifies that by letting you directly call functions on other Cloudflare workers.
In essenced, your code will go from looking like this:
await env.test.fetch('http://workerb/hello', {
method: 'POST',
body: JSON.stringify({params: 'World'})
})
to looking like this:
await env.test.hello('World')
- Each worker is either a service worker, or a consumer worker.
- A consumer worker can call functions from the service workers it's bound to.
- A service worker can only provide functions for consumer workers to call
npm i ergonomic-service-bindings
Add the following section to your wrangler.toml
:
[build]
command = "npm run build"
and change the main
section to point to:
main = "esb/index.js"
Next, in your package.json
, add a "build"
script:
"build": "ergonomic-service-bindings service"
Finally, ensure you have a file called src/service.ts
, which is where you'll be writing all your functions. Just export functions from here, and when you deploy your worker they'll be available to all services that bind your worker. For example, here's a hello world function:
export async function hello(name: string) {
return `Hello ${name}`;
}
npm i ergonomic-service-bindings
Add the following section to your wrangler.toml
:
[build]
command = "npm run build"
and change the main
section to point to:
main = "esb/index.js"
You'll also want to setup any service bindings to other workers you want to use. For instance, this binds to the worker called test
:
services = [
{ binding = "test", service = "test", environment = "production"}
]
Next, in your package.json
, add a "build"
script:
"build": "ergonomic-service-bindings consumer"
And that's it! Here's an example of calling the function hello
on a worker bound to test
:
export default {
async fetch(
request: Request,
env: Env,
ctx: ExecutionContext
): Promise<Response> {
return new Response(await env.test.hello('World'));
}
};
You don't need types for the functionality to work, but they definitely make the TS experience more pleasant. Simply define your env type within your consumer worker as follows:
export interface Env {
test: TestService;
}
where TestService
is imported from the autogenerated file at the path esb/service.types.ts
within your service worker directory!