4. Adding features to our serverless application

4 of 5

This page is part of Introduction to Compute, a step-by-step tutorial that shows you how to use Compute, Fastly's serverless computing platform. It builds on the concepts introduced in Introduction to Fastly's CDN, and it guides you through the process of setting up dependencies, creating a Compute application, and deploying it to the edge.

Now that we've successfully chained our Compute service to our VCL service, we can start modifying our serverless application to add features.

Setting response headers

In Introduction to Fastly's CDN, we set the surrogate-control and cache-control headers to assist with caching. Those are still present in our VCL service, and we're going to leave those intact since our VCL service is handling all of the caching in our service chain. But it's worth exploring how we can set response headers using our serverless application, if only as an academic exercise.

We can add a new header in our JavaScript code. For the purposes of this example, we'll create a fictional x-tacos header that has no effect on the client, but still appears in the response. We'll add some emoji tacos in the header's value to make things fun!

Using your text editor, open the src/index.js file in the taco-labs-compute directory. Delete the existing content, copy and paste the following code into the file, and then save it.

1/// <reference types="@fastly/js-compute" />
2
3const handler = async (event) => {
4 // get the request from the client
5 const req = event.request
6
7 const backendResponse = await fetch(req, {
8 backend: "vcl-origin",
9 cacheOverride: new CacheOverride("pass")
10 });
11
12 // Add headers to the response back to the client
13 backendResponse.headers.append("x-tacos", "๐ŸŒฎ๐ŸŒฎ๐ŸŒฎ")
14
15 // send the backend response to the client
16 return backendResponse;
17}
18
19addEventListener("fetch", event => event.respondWith(handler(event)));

This code is slightly different from our previous iteration. For one thing, we've modified the function to allow for asynchronous behavior. We've also better organized the code to change how the response to the client is structured. The request will be retrieved from the client, the object will be retrieved from our cache โ€” either our VCL service or, if the object isn't in cache, our origin server โ€” and then the header will be appended to the response and sent back to the client.

Now we can publish our changes by entering the following command in our terminal application:

$ fastly compute publish --version latest

This command builds and deploys our serverless application, and it activates a new version of our service configuration. Now we can check the headers by using the following curl command:

$ curl -svo /dev/null -H "Fastly-Debug:1" https://namely-modern-mosquito.edgecompute.app/tacos/

The output should look like this:

< HTTP/2 200
< x-amz-id-2: 0rBWx0c4DlzpxTLV57w41/Y/TyxFgZJ+nX+i+sthFy9wxsjf5973cHetB8DxQ3f0oO66YLcMU18=
< x-amz-request-id: 8PSH694YR3FMG5W0
< last-modified: Tue, 31 Jan 2023 17:36:47 GMT
< etag: "3c4d27191cfa47eedbe2a0ac06954a97"
< content-type: text/html
< server: AmazonS3
< via: 1.1 varnish, 1.1 varnish, 1.1 varnish
< cache-control: no-store, max-age=0
< surrogate-control: max-age=31557600
< accept-ranges: bytes
< age: 70424
< strict-transport-security: max-age=300
< x-tacos: ๐ŸŒฎ๐ŸŒฎ๐ŸŒฎ
< date: Fri, 10 Nov 2023 23:39:56 GMT
< fastly-debug-path: (D cache-bur-kbur8200032-BUR 1676652619) (F cache-bur-kbur8200032-BUR 1676652619) (D cache-bur-kbur8200032-BUR 1676652619) (F cache-bur-kbur8200056-BUR 1676582196) (D cache-chi-klot8100072-CHI 1676582195) (F cache-chi-klot8100142-CHI 1676582195)
< fastly-debug-ttl: (M cache-bur-kbur8200032-BUR - - 70424) (H cache-bur-kbur8200032-BUR - - 70424) (M cache-chi-klot8100072-CHI - - 0)
< fastly-debug-digest: 086cce689b77f680b0791868af574924c9252c43cb592d410909c434cdfd5c53
< x-served-by: cache-bur-kbur8200032-BUR
< x-cache: MISS, HIT, MISS
< x-cache-hits: 0, 1, 0
< x-timer: S1676652619.315891,VS0,VE7
< vary: Accept-Encoding
< content-length: 4320

We can see the x-tacos header in the output. Our changes worked! We can also see the surrogate-control and cache-control headers, so we know that those are still being provided by our VCL service.

For more information about adding or changing headers using Compute applications, refer to this code sample.

Creating a custom 404 response

In Introduction to Fastly's CDN, we created a custom 404 page using the Fastly web interface. If a client requested a web page that wasn't on our origin, Fastly would respond with our custom 404 page. That still happens now, too โ€” since our Compute service is chained to our VCL service, clients see that custom 404 page if they request a page that doesn't exist. But, as with response headers, we can update our serverless application to return a custom 404 response.

For the purposes of this example, we'll create a very simple response (โ€œThis is our custom Compute 404 pageโ€œ) that will be displayed in the client's web browser when they request a page that doesn't exist.

Using your text editor, open the src/index.js file in the taco-labs-compute directory. Delete the existing content, copy and paste the following code into the file, and then save it.

1/// <reference types="@fastly/js-compute" />
2
3const handler = async (event) => {
4 // get the request from the client
5 const req = event.request
6
7 const backendResponse = await fetch(req, {
8 backend: "vcl-origin",
9 cacheOverride: new CacheOverride("pass")
10 });
11
12 // Handle 404s with a custom response
13 if (backendResponse.status == 404) {
14 return new Response("This is our custom Compute 404 page", {
15 status: 404,
16 });
17 }
18
19 // If status is not 404, send the backend response to the client
20 if (backendResponse.status != 404) {
21 // Add headers to the response back to the client
22 backendResponse.headers.append("x-tacos", "๐ŸŒฎ๐ŸŒฎ๐ŸŒฎ")
23 return backendResponse;
24 }
25}
26
27addEventListener("fetch", event => event.respondWith(handler(event)));

We've refactored our code to handle two types of status codes: 404, and everything else. If our backend returns a 404 status code, our application will return the custom 404 response to the client. If the status code is not 404, we add the x-tacos response header and return the entire backend response to the client.

We can publish the changes by entering the following command in our terminal application:

$ fastly compute publish --version latest

As before, this command builds and deploys our serverless application and activates a new version of our service configuration. Now we can check to see if the custom 404 response is working by entering the URL of a non-existent page in our web browser, like https://namely-modern-mosquito.edgecompute.app/asdf. The custom 404 response should appear.

At this point, we could use the web interface to remove the custom 404 page from our VCL service, but it's not necessary. Our serverless application will return the new custom 404 response regardless of what the VCL service or S3 bucket returns.

Responding to 404s with a web page

We just modified our serverless application to respond to 404 errors with a custom response. That response was only a plain text response, however. How would we respond to a 404 error with a custom HTML web page?

There are two ways of going about this. We could include HTML in the body of our index.js file. That's not ideal for a couple of reasons, mainly because it would clutter up the file. A cleaner solution would be adding a new HTML file containing the HTML content of our 404 response and then using the includeBytes() function in our index.js file to include the HTML file in our response to 404 errors.

Using your text editor, open the src/index.js file in the taco-labs-compute directory. Delete the existing content, copy and paste the following code into the file, and then save it.

1/// <reference types="@fastly/js-compute" />
2
3import { includeBytes } from "fastly:experimental";
4
5// Load a static file as a Uint8Array at compile time.
6// File path is relative to root of project, not to this file
7const notfoundPage = includeBytes("./src/not-found.html");
8
9const handler = async (event) => {
10 // get the request from the client
11 const req = event.request
12
13 const backendResponse = await fetch(req, {
14 backend: "vcl-origin",
15 cacheOverride: new CacheOverride("pass")
16 });
17
18 // Handle 404s with a custom response
19 if (backendResponse.status == 404) {
20 return new Response(notfoundPage, {
21 status: 404,
22 });
23 }
24
25 // If status is not 404, send the backend response to the client
26 if (backendResponse.status != 404) {
27 // Add headers to the response back to the client
28 backendResponse.headers.append("x-tacos", "๐ŸŒฎ๐ŸŒฎ๐ŸŒฎ")
29 return backendResponse;
30 }
31}
32
33addEventListener("fetch", event => event.respondWith(handler(event)));

We've updated our code to add a new line at the top of the file to import the includeBytes() function. We've also added a line to load a new static HTML file (not-found.html), which we'll create in just a moment. Finally, we've updated the response for 404s to include the new static HTML file.

Now let's create the not-found.html HTML file in the src directory. Copy and paste the following code into the file, and then save it.

1<!DOCTYPE html>
2<html lang="en">
3 <head>
4 <title>404 not found</title>
5 </head>
6 <body>
7 <h1>404 Not Found</h1>
8 <p>Sorry! We couldn't find that content. Please try again.</p>
9 <p>This is a custom 404 response embedded in our Compute application.</p>
10 </body>
11</html>

Everything should be set. We can publish the changes by entering the following command in our terminal application:

$ fastly compute publish --version latest

Now we can check to see if the custom 404 page is working by entering the URL of a non-existent page in our web browser, like https://namely-modern-mosquito.edgecompute.app/asdf. Our custom 404 page should appear.

Creating a custom robots.txt file

Search engines use robots.txt files to figure out what content they can and can't index on a website. In Introduction to Fastly's CDN, we created a custom robots.txt page using the Fastly web interface. If a bot requested /robots.txt, Fastly would respond with our custom robots.txt page. That still happens now, too โ€” since our Compute service is chained to our VCL service, the robots.txt file is still returned.

Now that we know how to add custom files to our serverless application and return them in response to requests, we can update our serverless application to return a custom robots.txt response. Our original robots.txt file contained the following content:

User-agent: *
Disallow: /

For the purposes of this example, we'll update the content of the robots.txt file to allow content in the /tacos directory to be indexed:

1User-agent: *
2Disallow: /
3Allow: /tacos/

Open the src/index.js file in the taco-labs-compute directory, delete the existing content, copy and paste the following code into the file, and then save it.

1/// <reference types="@fastly/js-compute" />
2
3import { includeBytes } from "fastly:experimental";
4
5// Load static files as a Uint8Array at compile time.
6// File path is relative to root of project, not to this file
7const notfoundPage = includeBytes("./src/not-found.html");
8const robotsPage = includeBytes("./src/robots.txt");
9
10const handler = async (event) => {
11 // get the request from the client
12 const req = event.request
13 const reqURL = new URL(req.url)
14
15 const backendResponse = await fetch(req, {
16 backend: "vcl-origin",
17 cacheOverride: new CacheOverride("pass")
18 });
19
20 // Handle 404s with a custom response
21 if (backendResponse.status == 404) {
22 return new Response(notfoundPage, {
23 status: 404,
24 });
25 }
26
27 // Return robots.txt with a custom response
28 if (reqURL.pathname.endsWith("/robots.txt")) {
29 return new Response(robotsPage, {
30 status: 200,
31 });
32 }
33
34 // If status is not 404, send the backend response to the client
35 if (backendResponse.status != 404) {
36 // Add headers to the response back to the client
37 backendResponse.headers.append("x-tacos", "๐ŸŒฎ๐ŸŒฎ๐ŸŒฎ")
38 return backendResponse;
39 }
40}
41
42addEventListener("fetch", event => event.respondWith(handler(event)));

We've updated our code to load a new plaintext file (robots.txt), which we'll create in just a moment. We've also added a conditional to respond with the robots.txt file when bots request a URL ending in /robots.txt.

Now let's create the robots.txt file in the src directory. Copy and paste the following code into the file, and then save it.

1User-agent: *
2Disallow: /
3Allow: /tacos/

That should be it. We can publish the changes by entering the following command in our terminal application:

$ fastly compute publish --version latest

Now we can check to see if the custom robots.txt is working by entering https://namely-modern-mosquito.edgecompute.app/robots.txt in our web browser. The text of our custom robots.txt page should appear.

Adding redirects

When we remove content or rename a file on the Taco Labs website, we should redirect the old URL to the new one. This helps inform search engines that the old link is no longer available and that the new link should be indexed instead. In Introduction to Fastly's CDN, we used VCL snippets to redirect URLs. Now we can add redirects using our serverless application in conjunction with config store, a feature that stores key-value pairs and makes them available to Compute services.

You can interact with Config Store using the Fastly API or the web interface. We'll start by creating a new config store using the curl command to interact with the Fastly API. Enter the following command in your terminal application, replacing YOUR_FASTLY_TOKEN with the API token you created earlier:

$ curl -i -X POST "https://api.fastly.com/resources/stores/config" -H "Fastly-Key: YOUR_FASTLY_TOKEN" -H "Content-Type: application/json" -H "Accept: application/json" -d '{"name":"redirects"}'

We should see the following response:

HTTP/2 200
status: 200 OK
cache-control: no-store
content-type: application/json
fastly-ratelimit-remaining: 982
fastly-ratelimit-reset: 1677106800
accept-ranges: bytes
via: 1.1 varnish, 1.1 varnish
date: Wed, 22 Feb 2023 22:40:55 GMT
x-served-by: cache-control-cp-aws-us-east-2-prod-4-CONTROL-AWS-UE2, cache-bur-kbur8200116-BUR
x-cache: MISS, MISS
x-cache-hits: 0, 0
x-timer: S1677105656.843135,VS0,VE136
vary: Accept-Encoding
strict-transport-security: max-age=31536000
content-length: 144
{"name":"redirects","id":"abcdefgh12345","created_at":"2023-02-22T22:40:55Z","updated_at":"2023-02-22T22:40:55Z","deleted_at":null}

We'll use the web interface to link the config store to our Compute service and add the first redirect key-value pair. Log in to the Fastly web interface, click the Resources tab, and then select Config stores. You'll see the redirects config store, as shown below.

The redirects config store in the Fastly web interface

We need to link the config store to our Compute service so it can access the information in the config store. Click the Link to services button, select your Compute service, and click the Next button. Then click the Link and activate button to activate a new version of your service configuration and link the config store to the service.

Now we can add our first redirect. Let's pretend that Taco Labs is removing a web page for a failed initiative for taco kits and redirecting it to the taco page. We'll redirect /taco-kit to /tacos. We can use the web interface to add the key-value pair for the redirect, as shown below. The old URL is the key, and the new URL is the value.

Adding a redirect in the Fastly web interface

TIP

Config stores are versionless, so when you save the key-value pair, it's made available to your Compute service immediately โ€” no service configuration activation is needed.

With the config store and redirect successfully created and attached to our Compute service, we can turn our attention to our serverless application. Open the src/index.js file in the taco-labs-compute directory, delete the existing content, copy and paste the following code into the file, and then save it.

1/// <reference types="@fastly/js-compute" />
2
3import { includeBytes } from "fastly:experimental";
4import { ConfigStore } from "fastly:config-store";
5
6// Load static files as a Uint8Array at compile time.
7// File path is relative to root of project, not to this file
8const notfoundPage = includeBytes("./src/not-found.html");
9const robotsPage = includeBytes("./src/robots.txt");
10
11const handler = async (event) => {
12 // get the request from the client
13 const req = event.request;
14 const reqURL = new URL(req.url);
15 const reqPath = reqURL.pathname;
16
17 // Check if there is a redirect for the URL requested.
18 // If there is, redirect the client.
19 const config = new ConfigStore('redirects');
20 const dest = config.get(reqPath);
21
22 if (dest) {
23 return new Response("", {
24 status: 301,
25 headers: { Location: dest },
26 });
27 }
28
29 const backendResponse = await fetch(req, {
30 backend: "vcl-origin",
31 cacheOverride: new CacheOverride("pass")
32 });
33
34 // Handle 404s with a custom response
35 if (backendResponse.status == 404) {
36 return new Response(notfoundPage, {
37 status: 404,
38 });
39 }
40
41 // Return robots.txt with a custom response
42 if (reqURL.pathname.endsWith("/robots.txt")) {
43 return new Response(robotsPage, {
44 status: 200,
45 });
46 }
47
48 // If status is not 404, send the backend response to the client
49 if (backendResponse.status != 404) {
50 // Add headers to the response back to the client
51 backendResponse.headers.append("x-tacos", "๐ŸŒฎ๐ŸŒฎ๐ŸŒฎ")
52 return backendResponse;
53 }
54}
55
56addEventListener("fetch", event => event.respondWith(handler(event)));

We've refactored the code to use the ConfigStore constructor to access our redirects config store. We've also added some variables to obtain the pathname in the request, and some conditional logic to check incoming requests against the keys in the config store. If a redirect exists for the URL requested, our application will redirect the client to the new URL.

We can publish the changes by entering the following command in our terminal application:

$ fastly compute publish --version latest

Now we can check to see if the custom redirect is working by entering https://namely-modern-mosquito.edgecompute.app/taco-kit in our web browser. We should be redirected to https://namely-modern-mosquito.edgecompute.app/tacos. To add redirects in the future, we can add new key-value pairs using the web interface or the API.

Adding another domain and enabling TLS

The cheeky namely-modern-mosquito URL has served us well as we've developed our serverless application, but it's too long to print on a business card. It's time to add another domain now that we're close to moving this application to a production environment. We'll use https://compute.tacolabs.com to avoid conflicts with our other deployed websites.

The good news is that there's nothing inherently different about the process of adding a domain and enabling TLS for our serverless application. We can follow the instructions from Introduction to Fastly's CDN to generate a TLS certificate for the new domain and add the DNS records to AWS Route 53. Don't forget to add the new compute.tacolabs.com domain to your Compute service. Refer to our instructions on working with domains if you need a refresher.

TIP

In Introduction to Fastly's CDN, we configured our VCL service to handle TLS redirects for insecure HTTP requests. That's no longer necessary. Our Compute service will handle this automatically by only sending requests to our serverless application when a secure connection exists.

Configuring logging

As you learned in Introduction to Fastly's CDN, logging events and traffic is an important part of monitoring your website or application. When you're developing a serverless application, logs can be a critical part of troubleshooting errors and issues with your application on the Compute platform. And when you launch your serverless application into production, logs can provide valuable insight into how your application is performing.

Fastly provides a variety of logging options and features for Compute applications. When you're developing your application, you can view logs by previewing the application on your computer. After you upload your application to the Compute platform, you can use the log tailing feature to view real-time logs in your terminal application. And when your application is ready for the production environment, you can use Fastly's real-time log streaming feature to send logs to one or more third-party services.

Some application errors are logged automatically. You can also refactor your serverless application to customize the information written to your logs.

NOTE

Since we're chaining services and we already set up log streaming for the VCL service we configured in Introduction to Fastly's CDN, we'll have two sets of logs. Our VCL service will continue sending logs to our log streaming endpoint, and our Compute service will send logs to a different log streaming endpoint. Each set of logs will contain information specific to the respective service.

Running the server locally

The easiest way to view log output during development is to preview the application locally. We did this earlier when we created our Hello world application.

When you run the fastly compute serve command, the Fastly CLI compiles your application to Wasm and starts a local server to make it available for preview on your computer. As you send your serverless application requests using a web browser or terminal application, the server will continue to run in the background. You can view the real-time log output in your terminal application.

TIP

As previously discussed, the serverless application we're creating for Taco Labs can't be previewed locally since we're chaining services.

Using log tailing

After we've deployed our serverless application to the Compute platform, we can use the log tailing feature to view our application's logs in real time. When you run the fastly log-tail command, the Fastly CLI displays log lines in your terminal application as they're received from your application hosted on the Compute platform.

For example, if we deployed our serverless application and it had a bug causing an error, we could run the fastly log-tail command in our terminal application and try to load our application in a web browser. The error output will be displayed, similar to what's shown below.

$ fastly log-tail
INFO: Managed logging enabled on service 123456789abcdef
stdout | e663da7b | Log: Request:
stdout | e663da7b | Log: User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.3 Safari/605.1.15
stderr | e663da7b | Error while running request handler: e4.body is null
stderr | e663da7b | Stack:
stderr | e663da7b | bin/index.js/</d<@<stdin>:73:48
stderr | e663da7b | bin/index.js/</<@<stdin>:81:12
stderr | e663da7b | bin/index.js/<@<stdin>:86:11
NOTE

The log tailing feature isn't designed for use with production applications. If you're ready to start logging events from a serverless application deployed for production use, set up Fastly's real-time log streaming feature to send logs to one or more third-party services.

To write specific information to the log output while using the log tailing feature, we can customize our application's logs by refactoring our application. For example, if we wanted to see the request URL and the client's user-agent, we could add console.log() lines to our application, as shown below.

Open the src/index.js file in the taco-labs-compute directory, delete the existing content, copy and paste the following code into the file, and then save it.

1/// <reference types="@fastly/js-compute" />
2
3import { includeBytes } from "fastly:experimental";
4import { ConfigStore } from "fastly:config-store";
5
6// Load static files as a Uint8Array at compile time.
7// File path is relative to root of project, not to this file
8const notfoundPage = includeBytes("./src/not-found.html");
9const robotsPage = includeBytes("./src/robots.txt");
10
11const handler = async (event) => {
12 // get the request from the client
13 const req = event.request;
14 const reqURL = new URL(req.url);
15 const reqPath = reqURL.pathname;
16
17 // Prepare logs
18 console.log('Request: ' + reqURL);
19 console.log('User-Agent: ' + req.headers.get('User-Agent'));
20
21 // Check if there is a redirect for the URL requested.
22 // If there is, redirect the client.
23 const config = new ConfigStore('redirects');
24 const dest = config.get(reqPath);
25
26 if (dest) {
27 return new Response("", {
28 status: 301,
29 headers: { Location: dest },
30 });
31 }
32
33 const backendResponse = await fetch(req, {
34 backend: "vcl-origin",
35 cacheOverride: new CacheOverride("pass")
36 });
37
38 // Handle 404s with a custom response
39 if (backendResponse.status == 404) {
40 return new Response(notfoundPage, {
41 status: 404,
42 });
43 }
44
45 // Return robots.txt with a custom response
46 if (reqURL.pathname.endsWith("/robots.txt")) {
47 return new Response(robotsPage, {
48 status: 200,
49 });
50 }
51
52 // If status is not 404, send the backend response to the client
53 if (backendResponse.status != 404) {
54 // Add headers to the response back to the client
55 backendResponse.headers.append("x-tacos", "๐ŸŒฎ๐ŸŒฎ๐ŸŒฎ")
56 return backendResponse;
57 }
58}
59
60addEventListener("fetch", event => event.respondWith(handler(event)));

We can publish the changes by entering the following command in our terminal application:

$ fastly compute publish --version latest

Now we can start tailing the logs by entering the following command:

$ fastly log-tail

After viewing our serverless application in our web browser, we should see output similar to the following in our terminal application:

INFO: Managed logging enabled on service 123456789abcdef
stdout | f0a802ab | Log: Request: https://compute.tacolabs.com/mix-ins/
stdout | f0a802ab | Log: User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.3 Safari/605.1.15
stdout | 46e0e0db | Log: Request: https://compute.tacolabs.com/assets/logo.png
stdout | 46e0e0db | Log: User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.3 Safari/605.1.15

Our custom log entries are appearing in our terminal application!

Setting up a log streaming endpoint

Fastly's real-time log streaming feature allows you to send logs to one or more third-party services. As with the VCL service we created in Introduction to Fastly's CDN, you can configure a log streaming endpoint in the Fastly web interface. We'll set up a logging endpoint for Papertrail.

As our application was configured in the previous section, it will send logs to your terminal application while running the log tailing feature, but it won't send the logs to a log streaming endpoint. To do that, we'll need to refactor our application to import the Logger() constructor and write lines to our logs, as shown below. Open the src/index.js file in the taco-labs-compute directory, delete the existing content, copy and paste the following code into the file, and then save it.

1/// <reference types="@fastly/js-compute" />
2import { Logger } from "fastly:logger";
3import { includeBytes } from "fastly:experimental";
4import { ConfigStore } from "fastly:config-store";
5
6// Load static files as a Uint8Array at compile time.
7// File path is relative to root of project, not to this file
8const notfoundPage = includeBytes("./src/not-found.html");
9const robotsPage = includeBytes("./src/robots.txt");
10
11const handler = async (event) => {
12 // get the request from the client
13 const req = event.request;
14 const reqURL = new URL(req.url);
15 const reqPath = reqURL.pathname;
16
17 // Prepare logs
18 const logger = new Logger("tacolog");
19 logger.log('Request: ' + reqURL);
20 logger.log('User-Agent: ' + req.headers.get('User-Agent'));
21
22 // Check if there is a redirect for the URL requested.
23 // If there is, redirect the client.
24 const config = new ConfigStore('redirects');
25 const dest = config.get(reqPath);
26
27 if (dest) {
28 return new Response("", {
29 status: 301,
30 headers: { Location: dest },
31 });
32 }
33
34 const backendResponse = await fetch(req, {
35 backend: "vcl-origin",
36 cacheOverride: new CacheOverride("pass")
37 });
38
39 // Handle 404s with a custom response
40 if (backendResponse.status == 404) {
41 return new Response(notfoundPage, {
42 status: 404,
43 });
44 }
45
46 // Return robots.txt with a custom response
47 if (reqURL.pathname.endsWith("/robots.txt")) {
48 return new Response(robotsPage, {
49 status: 200,
50 });
51 }
52
53 // If status is not 404, send the backend response to the client
54 if (backendResponse.status != 404) {
55 // Add headers to the response back to the client
56 backendResponse.headers.append("x-tacos", "๐ŸŒฎ๐ŸŒฎ๐ŸŒฎ")
57 return backendResponse;
58 }
59}
60
61addEventListener("fetch", event => event.respondWith(handler(event)));

We can publish the changes by entering the following command in our terminal application:

$ fastly compute publish --version latest

Now we'll see our custom log entries in Papertrail, as shown below.

Adding a redirect in the Fastly web interface

Using version control

Since our serverless application consists of text files, it's a perfect candidate for version control. Using a version control system like git has numerous advantages. We could use git to track revisions to our serverless application, store it in a centralized location to share it with team members, and implement a formal development and review process to add features and fix bugs.

We've uploaded the serverless application used in this tutorial to GitHub. You can review the entire application on the GitHub website.

Setting up continuous deployment

Fastly has developed several Compute workflows for GitHub Actions, a continuous integration and deployment system integrated with GitHub that allows developers to test, build, and deploy applications to third-party systems. You can use these workflows to push your serverless application to the Compute platform when certain actions are performed, like after a pull request has been merged.

We'll use the following GitHub Action for our serverless application:

1name: Deploy Taco Labs Serverless Application
2on:
3 push:
4 branches: [fastly-compute]
5
6jobs:
7 deploy:
8 runs-on: ubuntu-latest
9 steps:
10 - uses: actions/checkout@v3
11
12 - name: Install project dependencies
13 run: npm install
14
15 - name: Deploy to Compute
16 uses: fastly/compute-actions@v5
17 env:
18 FASTLY_API_TOKEN: ${{ secrets.FASTLY_API_TOKEN }}

This workflow will automatically deploy our application to the Compute platform after every push to the fastly-compute branch.

Was this guide helpful?

Do not use this form to send sensitive information. If you need assistance, contact support. This form is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.