Write and test a function
Write the ES Modules handler of a function in Azion Console, read its response with Preview deployment, and find its log output.
You write the code of a function in JavaScript and read the response it returns, both in Azion Console. The function serves no traffic until an application or a firewall runs it.
Writing a function does not run it. A function runs when an application or a firewall instantiates it and a Rules Engine rule selects that instance. Four other pages carry the parts this one leaves out:
- For a guided first run, from an empty account to a response, refer to Functions quickstart.
- For what invokes a function and where it executes, refer to How Functions works.
- To run the function on an application, refer to Run a function on an application.
- To run the function on a firewall, refer to Run a function on a firewall.
Prerequisites
- An Azion account. To create one, refer to How to create an account on Azion.
- The Edit Functions permission on the account. It also requires the permission View Functions. Refer to Teams Permissions.
- Familiarity with JavaScript, including Strict mode.
Write the handler
A function exports a default object, and each property of that object is a handler. Where the instance is bound decides which handler runs: an instance on an application runs the fetch handler, and an instance on a firewall runs the firewall handler. This is the ES Modules pattern, the recommended way to structure a function.
A fetch handler receives the request and returns a Response:
The handler takes three parameters:
| Parameter | Type | What it carries |
|---|---|---|
request | Request | The incoming HTTP request: its method, its URL, its headers, and its body. |
env | Object | The environment variables and bindings of the function. |
ctx | Object | The execution context. ctx.waitUntil(promise) extends the lifetime of the execution past the point where the handler returns. |
request is the Web Request object. The handler branches on request.method, reads a cookie from request.headers, or parses the path with new URL(request.url). To call another system while the handler runs, use Fetch API.
The response carries whatever headers the code sets. This handler returns markup and declares the format in the content-type header:
A firewall handler decides whether the request reaches the application. ctx.deny() blocks the request immediately, and the request continues to the fetch handler when the code does not call it:
Azion Runtime makes strict mode the default and required option for the JavaScript of a function. Strict mode turns several silent JavaScript errors into thrown errors, and it blocks syntax that later ECMAScript versions may define. For the Web APIs the runtime implements and the full handler reference, refer to Azion Runtime.
Save the code in Azion Console
The code editor of a function is its Code tab in Azion Console. It is built on the Monaco Editor, with syntax highlighting, IntelliSense, and debugging. The context menu of the editor also carries a Format Document command. A new function opens with placeholder code that you replace.
To store the handler on a function:
Access Azion Console > Products Menu > Libraries > Functions.
Select the function you want to edit. To start a new one, select + Function and enter a name.
In the Code tab, replace the code with your handler.
Azion Console stores the code and makes the function available to instantiate. An instance names the function instead of holding a copy of it. The new code therefore reaches every instance that binds the function.
The editor also calls the ChatGPT APIs, so code explanation, generation, and refactor run inside the editor. The integration uses the credentials of your own OpenAI account, declared as a comment in the source code. For the credentials and the editor commands, refer to ChatGPT integration.
Test the response with Preview deployment
Preview deployment runs the function in Azion Console and shows the response the code returns, with no deployment. It calls PreviewProvider, an auxiliary function in the source code that builds a simulated request for the handler. The values inside PreviewProvider decide which path through the function runs. Change them and the same function answers a different request.
To read the response before the function serves traffic:
PreviewProvider builds the request the preview sends and returns the response the preview renders. For its shape, refer to PreviewProvider function.
The preview renders a text/html response as the page and an application/json response as the JSON body.
Change the method, the headers, or the URL of the simulated request to exercise another path through the handler. Read the output again.
The response of the function appears in Azion Console before any request reaches it.
Read the logs of a function
A function writes log messages with console.log, the same way JavaScript does in a browser. Azion collects that output and delivers it in three places: Azion CLI, Data Stream, and Real-Time Events. Until you open one of them, a function that fails and a function that never runs look the same.
To read the output from a terminal:
The terminal prints the console messages of the last 5 minutes and keeps printing new ones. Add --function-id to restrict the output to one function.
To read the same output in Azion Console, go to Real-Time Events and select the Functions Console tab. Each entry carries the level of the message, its line, and the identifier of the request that produced it.
When the logs do not explain the behavior, the symptom decides where to look next:
- Troubleshoot function execution and logs - the fixes for a function that never runs, stops early, or writes nothing.
- Debug functions on Data Stream - send the log output of a function to an endpoint you own.
- Query function logs with GraphQL API - query the events of a function from the GraphQL API.