Introduction
@serverlessQ/nextjs
is a lightweight wrapper to easily utilize message queues and cron jobs from ServerlessQ.
The version 2 has some amazing new features:
- Local file watcher: Create your API route with your message queue. We will deploy them automatically to ServerlessQ. No need to leave your IDE!
- Local Proxy: We've included a local proxy into the SDK. With that you receive enqueues messages and cron requests directly to your local machine. This brings your local machine even closer to production.
- Never leave your IDE: Create queues and crons from code.
The SDK is specifically for Next.JS projects. If the projects are deployed to Vercel we make use of Vercel's environment variables. But the SDK also works on any other deployment provider!
ServerlessQ is the missing piece on Vercel to add asynchronous tasks!
🚧 You need to use Next.JS minimum 12.2. You can use the enqueue
function with versions < 12.2, but you can't create new queues.
You can find the full docs for the SDK Version 2 here.
Installation
Install the library through your desired package manager
yarn add @serverlessq/nextjs
npm i @serverlessq/nextjs
pnpm i @serverlessq/nextjs
Environment Variables
SERVERLESSQ_API_TOKEN
You need to set the SERVERLESSQ_API_TOKEN
to connect your Next.JS project with ServerlessQ. The variable needs to be set during build time.
- Create an account on ServerlessQ and follow the steps described in our documentation to get the API token.
- Go to the dashboard, you will find your API token here
💡 If you application is deployed on Vercel, you can use our Vercel Integration to automate that task 🙂
If you want to use this library locally please create .env.local
file with the following value:
SERVERLESSQ_API_TOKEN=
Base URL
With the ServerlessQ SDK we forward the messages to the correct URL of your deployed Next.JS project. If the project is deployed on Vercel we make use of the VERCEL_URL
as base url. For example:
VERCEL_URL/api/queue
If your project doesn't run on Vercel, simply set the environment variable SLSQ_BASE_URL
.
SLSQ_BASE_URL=<your-production-url>
We will use this to prefix your generated resources so that they will point to your production resources e.g. https://my-cool-project.com/api/your-queue
New for you? Go check out the official next.js docs on how to create env files in NextJS
SDK Setup
Other than the environment variable there is only one more prerequisite to get the SDK running.
You need to add the function withServerlessQ
in your next.config.js
and wrap your next config with it.
const { withServerlessQ } = require("@serverlessq/nextjs");
module.exports = withServerlessQ({
});
This will enable two things:
- We run a local file watcher and deploy your newly created queues & cron jobs automatically to ServerlessQ. If they are created in development mode we prefix them with
DEV_
- We start a local proxy to allow you to receive enqueued messages and cron jobs on your local PC.
In order to keep track of what resources were created, we take advantage of a .serverlessq-config.json
file for local development and .serverlessq-config.production.json
for production builds. It is important to commit this file to your repository as it maps your created queue/cron id to the corresponding API function.
Creating Queues & Crons
Now let's see how to create Queues & Cron Jobs.
Queues
Create a new API Route within your Next.JS application, e.g. pages/api/queue
.
You can have several queues in multiple queue functions.
export default Queue({
options: {
name: "SendNewsletter",
route: "api/queue",
retries: 2,
},
handler: (req, res) => {
return res.status(200).json({ name: "John Doe" });
},
});
You need to define a few options:
name
: Unique in your ServerlessQ accountroute
: The relative route to your queue (in this case it is api/queue
)retries
: How often should failed requests fail?hander
: A function with the business logic that should be executed
Enqueue Jobs
You can now easily enqueue jobs by importing your created queue and call .enqueue(...)
.
You can do this either from getServerSideProps
or from another API function.
import { NextApiRequest, NextApiResponse } from "next";
import testQueue from "./queue";
export default async function enqueue(
req: NextApiRequest,
res: NextApiResponse
) {
const result = await testQueue.enqueue({ method: "GET" });
return res.json({ status: "success", ...result });
}
Cron Jobs
Creating a Cron job is as easy as creating a queue.
import { Cron } from "@serverlessq/nextjs";
import { NextApiRequest, NextApiResponse } from "next";
export default Cron({
handler: async (_req: NextApiRequest, res: NextApiResponse) => {
console.log("Hello from the cron!");
return res.status(200).json({ name: "John Doe" });
},
options: {
name: "Clean up",
expression: "0 */10 * * ? *",
retries: 3,
method: "GET",
},
});
You need to set the following options:
name
: Unique name for your cronexpression
: Your cron schedule. Please follow this syntaxmethod
: Which HTTP method should be used to call this handler?retries
: How often should failed requests be retried?
Security
Every request from our service contains a specific header x-serverlessq-signature
. This signature is a HMAC hash created from the request target and your API token. We use this signature to verify that the request is coming from our service. If you want to verify the request you can use our implementation verifySignature
or write your own.
import { verifySignature, Cron } from "@serverlessq/nextjs";
import { NextApiRequest, NextApiResponse } from "next";
export default Cron({
handler: async (_req: NextApiRequest, res: NextApiResponse) => {
if (!verifySignature(req, target)) {
return res.status(401).json({ status: "Unauthorized" });
}
console.log("Hello from the cron!");
return res.status(200).json({ name: "John Doe" });
},
options: {
expression: "0 */10 * * ? *",
retries: 3,
method: "GET",
name: "hello",
target: "api/cron",
},
});
Working with Existing Queues
You have also the opportunity to work with existing queues. If you have created a queue from the ServerlessQ UI and simply want to forward messages you can do that.
import { enqueue } from "@serverlessq/nextjs";
import { NextApiRequest, NextApiResponse } from "next";
export default async function handler(
_req: NextApiRequest,
res: NextApiResponse
) {
try {
const result = await enqueue({
target: "/api/queue",
method: "GET",
queueId: "ID_OF_THE_QUEUE",
});
res.json({ status: "success", ...result });
} catch (e) {
res.json({ status: "failed" });
}
}
You can use the enqueue
function to directly enqueue a job to a certain Queue-ID
. You find your queue ID in the ServerlessQ Dashboard
Cleanup
We offer the possibility to clean up all dev resources when closing the development server. This happens by checking on different exit signals and deleting the resources when one is received. To enable this feature, update your package.json
like this:
{
"scripts": {
"dev": "NEXT_MANUAL_SIG_HANDLE=true next dev",
"build": "next build",
"start": "next start"
}
}
Types
We have full TypeScript support of course ✨
Support
If you need help with anything join our Discord server and hit us up! 💬
Verbose Logs
If you encounter errors while using the SDK you can enable verbose logs by setting the environment variable SLSQ_VERBOSE
to true
in your .env.local
file. This will give you more information about the error and the SDK lifecycle. Feel free to attach these logs to your support request.
Example Project
We have an example project in our GitHub repository
Port
If you're project runs another port than 3000 please start your dev server with the environment variable PORT
. E.g. PORT=4040 yarn dev
.
Known Bugs
There are a few known bugs with Next.JS versions. Please try to use other versions.
- 13.1.6: Resources will be created multiple times.
versions > 13.4.10
: No shutdown command is executed - you can use this version, but your resources will not be cleaned up.
License
The MIT License.