First Worker
Task
Enhance AcmeCorp's API to return additional data by putting a simple Worker in front of it.
You can find more Worker use cases in our Examples.
Why
- Workers allow you to augment web traffic without modifying the origin server
- They can also help you scale by offloading some compute from the origin server
- And they let you leverage Cloudflare's global network for high availability and low-latency content delivery
Steps
We will be build a worker demonstrating how to augment API responses without modifying the origin. By the end of this exercise, you will have a better understanding of how to intercept requests and modify responses using Cloudflare Workers.
1. Create DNS record for API
First, add a DNS record for AcmeCorp's API by selecting Websites in Cloudflare dashboard and selecting your zone. Then under DNS select Add record and add the following:
Type: A
Name: api
IPv4 address: 4.157.169.241
Proxy: yes
The final result should look like this:
When confirmed, exit the zone configuration by clicking on the account name.
Now let's have a look at the /orders
endpoint of that API and see what it returns:
$ curl -s https://api.cfdemolab-zone-xxx.cfdemolab.xyz/v1/orders/1
⚙️ nocopy
{
"id": 1,
"title": "Ustilo condico ducimus stella.",
"createdBy": {
"name": "Marcel Aufderhar"
},
"createdAt": {
"name": "Mon Apr 22 2024 16:31:20 GMT+0000 (Coordinated Universal Time)"
},
"items": [
{
"id": 0,
"productName": "Awesome Car",
"productUuid": "bf36c9e3-d301-4aae-b6c2-2f9f50970213",
"quantity": 6,
"unitPrice": 209
},
{
"id": 1,
"productName": "Gorgeous Car",
"productUuid": "7e48e77c-4f97-4e74-b43b-559879860acf",
"quantity": 8,
"unitPrice": 224
}
],
"archived": false,
"success": true
}
So we have an API that returns a list of items for a specific order, together with quantity and unit price. Now let's imagine this API is being integrated with a new system and you're faced with these requirements:
- The new system needs the API to also return total price of each item (
unitPrice * quantity
) - There are existing systems that integrate with the API and are sensitive to data they receive, make sure the data structure remains the same for those
Let's see if we can solve this with a Worker!
2. Create a Worker
In your Cloudflare dashboard, navigate to Workers & Pages and create a new Worker:
Give the Worker a Name and Deploy it:
Once deployed, click Edit code.
And replace your Worker's code with the following and Deploy it again:
3. Add route for Worker
As a last step, make sure this Worker gets executed on all /orders
requests from your API by opening the Worker in dashboard and then adding a new route under Settings ‣ Triggers ‣ Routes ‣ Add route.
Select you Zone, add a route for api.<your_zone>/v1/orders/*
and select Fail open.
This tells Cloudflare to send requests to the /orders
endpoint to your Worker instead of sending them to the origin.
The Fail open sends requests to other endpoints directly to the origin, bypassing this Worker.
4. Test Worker
If you now issue the same request you did at the beginning, nothing changes and we retain the requested backwards compatibility.
You can verify that the request was actually handled by your Worker by opening the Logs tab and selecting Begin log stream:
If you now add a header X-Api-Preference:include_total
to your request, you should see totalPrice
being included with each item.
curl -s https://api.cfdemolab-zone-xxx.cfdemolab.xyz/v1/orders/1 -H "X-Api-Preference:include_total"
⚙️ nocopy
{
"id": 1,
"title": "Angustus civitas perspiciatis.",
"createdBy": {
"name": "Robin Lesch"
},
"createdAt": {
"name": "Thu Dec 07 2023 17:03:18 GMT+0000 (Coordinated Universal Time)"
},
"items": [
{
"id": 0,
"productName": "Handmade Shoes",
"productUuid": "8ae94b9f-2437-498c-9c08-ce6c886a41c3",
"quantity": 6,
"unitPrice": 507,
"totalPrice": 507
},
{
"id": 1,
"productName": "Handcrafted Gloves",
"productUuid": "4e6e1e15-b5ee-4578-a389-b2ece1d3e3ef",
"quantity": 10,
"unitPrice": 594,
"totalPrice": 594
}
],
"archived": false,
"success": true
}
Looks good, altho there is a problem... You may have noticed that the totalPrice
is just a unitPrice
.
5. Challenge
Can you go back to the Worker's code and fix it by calculating the actual total price for each item?
And for extra points (optional), can you also calculate and return the total price of the whole order?