In this article, we will discuss a simple way for you to map a Cloudflare worker on a subdomain on your website.
Let’s say you have a website (example.com) from where you want to call an external API on https://some-api.com/path/to/resource?apikey=xyz
.
Ordinarily, you will have to call this API on your backend by setting up a dedicated server. You will also need to create a wrapper API that you have to maintain.
That’s just extra cost and time investment for such a small task.
This is where the Cloudflare Workers come to the rescue. You can use these workers on your subdomain (api.example.com
) or a dedicated path (example.com/api/path/to/resource
) to run logic on Cloudflare’s servers without setting up a server or managing yet another service for your website/app.
A specific example.
Let’s suppose you want to call https://some-api.com/path/to/resource?apikey=xyz
from your website example.com
.
In your client-side js, you could do something like this.
const getApiResponse = async () => {
try {
const apikey = "xyz";
const res = await fetch(
`https://some-api.com/path/to/resource?apikey=${apikey}`
);
const { data } = await res.json();
return data;
} catch (error) {
console.error(error);
} finally {
console.log("done");
}
};
getApiResponse();
This, I must admit will work fine. But there is an issue with this approach.
- You have to embed the
apikey
on your client. - In case the API is of your own backend (eg Firebase HTTPS Functions, AWS Lambda), then it is susceptible to a DDoS attack since the URL is exposed to the world.
Granted, not all applications will have these issues, but some of them in the wild definitely do suffer from these.
Also, I’d like to point out that lots of API services allow origin
restrictions to protect unauthorized API usage. Case in point Google Maps. But, again, not all API providers have this feature.
Here, we can easily add Cloudflare Workers in the middle of your API request.
Initial Setup
- Add your domain to Cloudflare. There is a very helpful tutorial on the Cloudflare community for just that. You should follow this and then come back here.
https://community.cloudflare.com/t/step-1-adding-your-domain-to-cloudflare/64309
Creating a Worker
- Go to the Workers tab in the Cloudflare Dashboard.
- Click on the
Manage Workers
button to go to theWorkers
screen. - On the top-right button
Create a Worker
. - Click on
Save and Deploy
. Right now, leave the existing code intact. We will touch that later.
addEventListener("fetch", (event) => {
event.respondWith(handleRequest(event.request));
});
/**
* Respond to the request
* @param {Request} request
*/
async function handleRequest(request) {
return new Response("hello world", { status: 200 });
};
- Go back to the Workers screen again and click on the
Add route
button and addhttps://api.example.com/*
in theRoute
and your new worker name in theWorker
field. - Click
Save
.
Updating DNS
- In the Cloudflare Dashboard, click on the
DNS
tab where you will see theDNS Management
screen. - Click on the
+ Add Record
button and add aCNAME
DNS
record with the following details.
Type: CNAME
Name: api
IPv4 Address: api.example.workers.dev
TTL: Auto
Proxied: Yes
Proxying Requests from Cloudflare Edge
This is the final part of your worker. Here’s the code.
const apikey = "xyz";
const MAIN_API = "https://some-api.com";
addEventListener("fetch", (event) =>
event.respondWith(handleRequest(event.request))
);
/**
* @param {Request} request
*/
const handleRequest = async (req) => {
try {
const { url, method, headers } = req;
const { pathname, search } = new URL(url);
const body = await req.text();
const requestForwardingUrl = new URL(pathname, MAIN_API);
const params = new URLSearchParams(search);
// API_KEY is required in every request.
params.append("apikey", API_KEY)
// All other params from the example.com url will be added
// to the fetch request.
[...params.entries()].forEach(([value, key]) => {
requestForwardingUrl.searchParams.append(key, value);
});
return fetch(requestForwardingUrl.href, {
method,
headers,
body: method === "GET" ? undefined : body,
});
} catch (error) {
console.error(error);
return new Response(JSON.stringify({ message: "Something went wrong" }), {
status: 500,
});
}
};
Every request to the api.example.com
is sent to Cloudflare DNS. The Cloudflare DNS then intercepts this request and check the CNAME
linked to this domain.
A request to api.example.com/path/to/resource
will be sent to https://some-api.com/path/to/resource
.
In addition to this, the Worker will also add the apikey
query param to the request sent to the some-api.com
.
Leave a Reply