Fast access to regional AWS endpoints from Cloudflare Workers
When using a CDN together with Edge compute to optimize your frontend for fast page load times, it’s also important to bring your data as close to your users as possible. Sometimes cross-region data replication and latency-based routing are enough. Other times, a more sophisticated solution is in order.
Say you store your data in a DynamoDB global table and have it replicated across multiple AWS regions. There’s no “global” DynamoDB endpoint that will automatically forward requests to the nearest replicated region for you. As a result, making fast network calls from the Edge to AWS services isn’t as trivial as it should be.
That’s even the case with Lambda@Edge, where you can use the AWS_REGION
environment variable to geo-route requests inside the function handler, but still need to compare distances yourself when a request comes from a location without a replica (or fall back to a potentially slow default region).
Inspired by my work at Grafbase, I tried to tackle this problem for Rust in general and Cloudflare Workers in particular. That’s why I’ve open-sourced a library called aws-region-nearby for finding the region closest to a user’s geographic location.1
Workers example
aws-region-nearby includes a Cloudflare Workers example that tells visitors the name of the nearest AWS region based on the latitude and longitude of incoming HTTP requests (as provided by Cloudflare along with many other properties):
use worker::*;
#[event(fetch)]
pub async fn main(req: Request, env: Env, _ctx: Context) -> Result<Response> {
Router::new()
.get("/", |req, _ctx| {
let (latitude, longitude) = req.cf().coordinates().unwrap();
let region = aws_region_nearby::find_region(latitude, longitude);
Response::ok(region.name())
})
.run(req, env)
.await
}
The fastest way to test this code is to start a development server on localhost with the wrangler CLI tool:
❯ wrangler dev
🌀 Running worker-build --release
[INFO]: 🎯 Checking for the Wasm target...
[INFO]: 🌀 Compiling to Wasm...
...
[INFO]: ✨ Done in 48.19s
[INFO]: 📦 Your wasm pkg is ready to publish at ...
👂 Listening on http://127.0.0.1:8787
wrangler dev
actually runs your code on Cloudflare’s edge network – a rather unexpected behavior that makes for easy local testing. For example, here’s what the Worker returns when calling it from where I live, just outside of Hamburg, Germany:
❯ curl http://127.0.0.1:8787
eu-central-1
I checked that the region is updated correctly by connecting to different VPN servers, including one in Sweden:
❯ curl http://127.0.0.1:8787
eu-north-1
Use with AWS SDKs
Besides Workers, I wrote another example showing how to integrate aws-region-nearby with Rusoto (in maintenance mode) and the official AWS SDK for Rust.2
Among other things, the code demonstrates how to select the closest replicated region via find_region_from_list
:
use aws_region_nearby::{find_region_from_list, AwsRegion::*};
let replica_regions = [
UsWest1,
UsEast1,
EuCentral1,
ApNortheast1,
];
let region: rusoto_core::Region =
find_region_from_list(latitude, longitude, &replica_regions)
.name()
.parse()
.unwrap();
println!("Rusoto region = {:?}", region);
In summary, aws-region-nearby helps you reduce latency by leveraging serverless Rust applications at the Edge and fetching data from geographically replicated endpoints.
-
By applying the haversine formula as implemented by the geoutils crate. ↩
-
Combining the two examples – talking to AWS APIs from Cloudflare Workers – is outside the scope of this post. Suffice to say, the mentioned Rust SDKs don’t compile to Wasm out of the box. More on this soon. ↩