Query a database from a function
Read rows from SQL Database inside a function with the azion:sql runtime module, and return them in the response the function sends.
You read rows from a database in SQL Database inside a function, during the request the function handles. The azion:sql runtime module opens the connection and runs the SQL.
This page carries one worked function. For every method the module exposes, refer to SQL Database API.
Prerequisites
- An application to instantiate the function on. Refer to Instantiate a function on an application.
- A personal token to authorize the API requests.
- The Edit SQL Database permission, which grants permission to create and edit databases and their data through the Azion API. Refer to Teams Permissions.
- SQL Database enabled on your account. The product is in Preview and is not enabled by default, so request access through Technical Support.
Create the database and the table
The function reads a table that already exists, so the two calls below are the shortest path to one. To create the database and fill it with rows:
The API answers with HTTP 202 and returns the identifier the next call takes in its path:
Provisioning takes roughly 15 seconds. Send GET /databases/{database_id} until status reads created.
The API answers with HTTP 200 and "state": "executed", and data carries one entry per statement, in the order you sent them.
The database mydatabase holds a users table with three rows. The name you set here is the name the function passes to Database.open.
In the Modernize a monolithic application without a rewrite use case, this section takes these values:
| Setting | Value |
|---|---|
| Database | stores-db |
Write the function
Database.open opens a connection to the read replica of the database, so a function reads the data and does not write to it. The handler below answers a GET request with the contents of users:
connection.query returns a rows handle. rows.columnCount() and rows.columnName(i) name the columns, rows.next() advances one row and returns a falsy value once the result set is exhausted, and row.getString(i) reads a cell by its position. The sample joins the cells of a row with | and the rows with a line break, then sends the text as the response body. A failure inside the module is logged with e.message and e.stack and returned as HTTP 500.
Instantiate and run the function
A function runs only after it is bound to an application and a rule on that application selects it. To run the function and read the rows:
Access Azion Console and create a function that carries the code above. Refer to Functions.
Bind the function to the application that serves your domain, then add the rule that runs the instance. Refer to Instantiate a function on an application.
The response carries the column names on the first line and one line per row of users:
Return rows as JSON
A function that answers an API route returns the rows as a JSON array instead of text. The example answers GET /api/stores with the rows of a stores table in a database named stores-db, created as Create the database and the table shows, on the domain www.example.com. The function reads the database through the Azion.Sql global, which takes the database name and no token.
To create the stores table and load its rows, replace <database-id> with the id of stores-db:
The API answers 200 with one entry per statement. Read data[].error on each entry: a failed statement also returns 200, with error in place of results.
Create a function named stores-route with this code, and instantiate it on the application as stores-route. For the steps in each interface, refer to Functions quickstart, which creates a function and instantiates it on an application.
The function reads every row in order and answers with a JSON array. A failure to open or query the database answers 503, so a fault in the route shows up as a 5xx on that path alone.
To confirm, run the instance on GET /api/stores, as Run a function on one path, and roll it back shows, and request the route:
The body holds the rows of the stores table:
The Modernize a monolithic application without a rewrite use case uses the values of this example.
These checks confirm the Modernize a monolithic application without a rewrite use case.