This directory is an example of a Next.js app connected to a MySQL database using the @now/next and @now/node Builders.
The main purpose of this example is to highlight how MySQL can be used successfully in a serverless architecture. For a more detailed explanation of Next.js you can visit the documentation or view other examples in this repository such as a Next.js only build.
This example consists of three directories:
/api
- which contains the serverless lambda functions to be deployed inside/profiles
/lib
- which is where the database connection helper is stored/pages
- where the data received is displayed by Next.js
The example includes a now.json
file, used to configure your build when deploying to Now, and a .nowignore
file, used to prevent uploading unnecessary source paths to Now, keeping deployment times short.
Also included is a db.sql
file, which has the example data and SQL commands, this can be used to replicate this example.
Lastly, the next.config.js
is used to tell Next.js that we are targeting a serverless environment.
Serverless functions will create multiple database connections as traffic increases and therefore all available connections can be consumed quickly, blocking access for others. This example resolves this issue by utilizing Jeremy Daly's MySQL wrapper - serverless-mysql.
The wrapper provides basic but important functionality that allows connections to be monitored, limited, retried and closed. This is vital for making serverless MySQL work and is explored further in db.js
below:
const mysql = require('serverless-mysql');
const db = mysql({
config: {
host: process.env.MYSQL_HOST,
database: process.env.MYSQL_DATABASE,
user: process.env.MYSQL_USER,
password: process.env.MYSQL_PASSWORD
}
});
exports.query = async query => {
try {
const results = await db.query(query);
await db.end();
return results;
} catch (error) {
return { error };
}
};
db.js
performs the following actions:
- Requires the
serverless-mysql
package - Creates a connection to the database using pre-defined environment variables
- Exports a query helper that enforces the
db.end()
method
The most important part, in the serverless context, is db.end()
.
By using await db.end()
, serverless-mysql
ensures the connection is closed before sending the response to the client.
As a result, it ensures that concurrent MySQL connections do not reach their limit, allowing new connections to be created when required.
Next, let's look at /api/profiles/profile.js
to see what a serverless MySQL query looks like:
const db = require('../../lib/db');
const sql = require('sql-template-strings');
module.exports = async (req, res) => {
const [profile] = await db.query(sql`
SELECT *
FROM profiles
WHERE id = ${req.query.id}
`);
res.status(200).json({ profile });
};
index.js
performs the following actions:
- Requires the database connector found in
/lib
, along with theurl
andsql-template-strings
modules - Parses the request url to get the query parameters
- Sends a query to the database to get a single profile
- Sends the profile to the client as a response
As you can see, once the connection is created, querying the database is straightforward and easy to follow.
Using this format, you can create whatever queries you require simply by changing the parameter passed to db.query()
- simple but incredibly effective, not to mention performant.
To deploy your own version of this example follow the below steps:
- Create a remote MySQL database noting down the host, username, password and database name
- Clone this repository using and
cd
into it - Install the dependencies with
yarn
- Add the environment variables from the first step using
now secrets add <ENV_NAME> <VALUE>
- the variable names can be found innow.json
- Populate your MySQL database with the data found in
db.sql
using your preferred method - Deploy your application using a single command -
now
Congratulations, you've just deployed your very own Next.js + MySQL application!
For more information on how you can deploy your own Next.js + MySQL applications, see the following resources: