Announcement: Testing Cloudflare Workers via LocalStack Extensions

In this post, we showcase how Cloudflare Workers can be easily tested locally in the LocalStack platform, using our novel LocalStack Extensions mechanism.

Cloudflare is an internet service provider focusing on the content delivery network (CDN) and web security services. One of the key features in their service offering is Cloudflare Workers, a platform to run JavaScript service workers at the Edge. It allows users to inject functionality like setting user cookies, performing web redirects, modifying served content via search/replace, rewriting URLs, etc.

LocalStack is a cloud service emulator that can run in a single container on your local machine or in your CI environment, which lets you run your cloud and serverless applications without connecting to an AWS account. Please check out the Getting Started guide in the LocalStack documentation for more information.

LocalStack Extensions

With version 1.0 of LocalStack, we have introduced Extensions that allow developers to extend and customize LocalStack. You can use Extensions to add new services, extend existing services, and even add custom functionality.

Below is a simple example extension called MyExtension, which illustrates the different lifecycle hooks, and how they relate to the request processing inside your LocalStack instance. One of the extension hooks is update_gateway_routes(..) which allows adding custom HTTP routes to the request processing middleware of the LocalStack Gateway Router. It allows us to add arbitrary API endpoints to LocalStack, accessible through the canonical edge port 4566, i.e., under http://localhost:4566/<path_of_my_extension>.

Cloudflare Workers emulation - Miniflare

The Cloudflare team has released a local emulator called Miniflare that allows users to run the JavaScript code of Cloudflare Workers locally.

While Miniflare is great, it only covers a subset of the functionality required for full local testing. Most importantly, Miniflare allows to start of Cloudflare Workers in a local development server (e.g., running on http://localhost:8787), but it does not emulate the actual Cloudflare API used to create users, services, deployments, etc.

Ideally, we would like to test the full workflow end-to-end in a local environment that mimics the production system. For example, one of the main tools to develop Cloudflare Workers is wrangler, a framework and CLI that simplifies the development and deployment of Workers. Below is a simple CLI example that illustrates how to create a sample app via an interactive wizard (wrangler init) and then deploy the application to the Cloudflare production environment (wrangler publish).

# create demo application in local directory
$ wrangler init
...
# publish application to Cloudflare
$ wrangler publish
...

Wouldn’t it be great to run the production wrangler commands against an emulator to facilitate local testing? This is where the Cloudflare LocalStack Extension comes into play!

Cloudflare LocalStack Extension

The Cloudflare LocalStack Extension uses the update_gateway_routes(..) extension lifecycle hook to define an additional endpoint http://localhost:4566/miniflare that is served directly inside the LocalStack instance. Note that the extension provides more functionality than the miniflare emulator - we also provide a (very simplistic) emulated/mocked version of the Cloudflare API, which allows users to create local services, script uploads, deployments, etc.

Upon local deployment via the wrangler CLI, the extension receives the deployment requests under the /cloudflare/... endpoint. It then starts the miniflare process inside the LocalStack container and makes it accessible under a new local endpoint like w1.cloudflare.localhost.localstack.cloud (this domain name resolves to 127.0.0.1). The client can now use this endpoint to invoke the deployed Worker via the Web browser or an HTTP client like curl.

Installing the extension

To install the extension, make sure you have LocalStack Pro running (you can get a free trial API key) and the latest version of the localstack CLI installed - then the extension can be installed via the following command:

$ localstack extensions install "git+https://github.com/localstack/localstack-extensions/#egg=localstack-extension-miniflare&subdirectory=miniflare"

Using the extension

To use the extension, we can simply use the wrangler CLI after exporting the relevant environment variables CLOUDFLARE_API_BASE_URL and CLOUDFLARE_API_TOKEN, which cause wrangler to run the deployment requests against the LocalStack extension.

$ export CLOUDFLARE_API_BASE_URL=http://localhost:4566/miniflare
$ export CLOUDFLARE_API_TOKEN=test 
$ wrangler publish
...
> hello@0.0.0 deploy
> wrangler publish

 ⛅️ wrangler 2.6.2
-------------------
Total Upload: 0.21 KiB / gzip: 0.18 KiB
Uploaded hello (0.05 sec)
Published hello (3.03 sec)
Current Deployment ID: bcf48806-b317-4351-9ee7-36e7d557d4de

Once deployed, the Cloudflare worker can be easily invoked via curl:

$ curl http://hello.miniflare.localhost.localstack.cloud:4566/test
Hello World!

Conclusion and Next Steps

In this short post, we have demonstrated how to easily test Cloudflare Worker applications locally using the LocalStack Cloudflare Extension. The scope of this extension goes beyond the capabilities of miniflare. In addition to serving the Workers, it also provides a (very simple) emulated version of the actual Cloudflare API, allowing us to use production tools like wrangler to develop, deploy, and test our Workers applications locally.

At LocalStack, we continue to invest in our Extensions mechanism and provide emulators that go beyond our core scope of running AWS apps locally - aiming to become the go-to platform for running emulators for any kind of API or managed service out there!

We would love to hear your thoughts, and whether you have ideas for new LocalStack Extensions we could develop - looking forward to getting your feedback! :rocket:

2 Likes