In the fast-paced development world, imagine having the power to effortlessly create, deploy, and manage serverless functions within your app, all while streamlining your development process.
Technology overview
Appwrite functions allow you to run backend code automatically in response to events triggered by Appwrite or by executing the code on a predefined schedule. Your code is securely stored on your Appwrite instance and is executed in an isolated environment.
When users of your application create an account or log in, you can define code in Appwrite functions to run and execute based on system events. Appwrite functions support multiple runtimes (like Node.js, Python, and PHP) and allow you to schedule the functions in your code to run at specific time intervals with your specified runtime.
Additionally, you can seamlessly create and deploy your functions by running commands in your terminal with the Appwrite CLI (which enables you to work with the Appwrite server).
Appwrite Cloud is an extension of the open-source version of Appwrite. It comes with all the services included in the open-source version but now boasts a fully managed service and minimum friction.
Project overview
This article takes a closer look at the magic of Appwrite Functions 1.4, demonstrating how to migrate your Appwrite version 1.3 functions to the latest version and take advantage of its new features and syntax changes in a Next.js application.
GitHub
Check out the complete source code here.
Prerequisites
To follow along with this tutorial, you should have a working knowledge of the following:
- Basic understanding of JavaScript and Next.js
- Installation of the Appwrite CLI
- An Appwrite Cloud account; you can sign up here
What’s new in Appwrite Functions 1.4
In Appwrite 1.4, Functions are more accessible to learn, faster to debug, painless to maintain, and more flexible than ever. The Functions workflow has been reimagined, guided by the community’s help and feedback.
Below are some notable changes in the Appwrite Functions 1.4:
- First,
template
codes have been introduced to Appwrite 1.4 Functions. You can add Functions engineered by the Appwrite team and community to your Appwrite project. You can start leveraging the powers of Appwrite Functions and the community without writing a single line of code. - Also, the Functions syntax has been revised based on feedback. The request data will now contain all the expected components of a typical
HTTP
request. - A new dedicated
log
method has been included, so you’ll never have disappearing logs on a function you’re trying to debug again. - Finally, in 1.4, you can deploy Appwrite Functions directly from Git. Appwrite Functions will now fit into your existing workflow alongside the rest of your code.
In this tutorial, you’ll start with setting up a frontend app for a demo that eventually illustrates the difference and migration from 1.3 to 1.4.
Frontend setup
The frontend is a basic Next.js form page that handles form submissions and can be used to store a user's information in a collection. The form is submitted to the function using the POST
method, and the form data will be sent as a URL-encoded string in the request body.
To set up your application, you'll clone this repository using the command below:
git clone https://github.com/Tundesamson26/appwrite-functions-guide.git
Then, run the command below in the project directory:
$ cd appwrite-functions-guide
$ npm install
This repository contains all the initial setups you'll need for your app, helping you focus on your app's main functionality.
Then, run the development server using the command below:
npm run dev
Once the development server runs, you can view it on your browser at http://localhost:3000.
Creating an Appwrite Cloud project
To get started, log into Appwrite Cloud, click the Create project button, input appwrite-functions-guide
as the name, and then click Create.
The project dashboard will appear on the console. Next, copy the Project ID; you’ll use this to set up your Next.js application.
You will also need to get an API Key
, which will be useful in the next step. To create an API Key
, click on the project overview and then click on API Key
with the name functions_guide
.
Next is to choose which permission scopes to grant your application. In this case, choose Functions and Databases and click on Create.
Creating functions in Appwrite 1.3
To create a function in Appwrite 1.3 version and below, you will start by logging onto Appwrite's console using the Appwrite CLI, like so:
appwrite login
Running the command above requires you to use your Appwrite credentials
(i.e., your Appwrite email and password) in the terminal.
After logging into the application, you will initialize and link the Next.js application with the previously created Appwrite project. To do so, you will run the command below:
appwrite init project
Running the command above will display a list of options from which you will pick those appropriate for your project.
Next, create a function in your Next.js application by running the command below:
appwrite init function
Upon the successful execution of the above command, you will see a new folder named functions/<function-name>/src/index.js
in your Next.js application.
Appwrite Functions 1.3 logic
In order for your Appwrite Functions 1.3 to handle the form submissions, navigate to src/index.js
and paste the code below:
const sdk = require("node-appwrite");
const querystring = require ("node:querystring");
module.exports = async (req, res) => {
if (req.method === "GET") {
return res.send(html, 200, { "content-type": "text/html" });
}
if ( req.method === "POST" && req.variables.headers["content-type"] === "application/x-www-form-urlencoded") {
const formData = querystring.parse(req.body);
const message = {
name: formData.name,
email: formData.email,
date: formData.date,
time: formData.time,
content: formData.content,
};
const client = new sdk.Client();
client
.setEndpoint(req.variables['https://cloud.appwrite.io/v1'])
.setProject(req.variables['APPWRITE_FUNCTION_PROJECT_ID'])
.setKey(req.variables['APPWRITE_FUNCTION_API_KEY'])
.setSelfSigned(true);
const databases = new sdk.Databases(client);
const document = await databases.createDocument(
"650efb16ae5ebb92185a",
"650efb593f6c9f97c09c",
ID.unique(),
message
);
return res.send("Message sent");
}
return res.send("Not found", 404);
};
The code block above achieved the following:
- Imported the node-appwrite SDK from Appwrite.
- Exported an asynchronous function req and res using the Appwrite serverless function framework
-
GET Request Handling:
- If the incoming request method is
GET
, then the function sends an HTML response (text/html) with the html content. The response code is set to200
, indicating a successful response.
- If the incoming request method is
-
POST Request Handling:
- If the incoming request method is
POST
and the content type in the request headers is 'application/x-www-form-urlencoded', then the function proceeds to handle thePOST
request. - It parses the request body (which is assumed to be in URL-encoded format) using
querystring.parse
to extract form data. - It creates a message object containing properties like name, email, date, time, and content by extracting data from the parsed form data.
- It creates an instance of the Appwrite client using the
sdk.Client()
. - It configures the client with an
Endpoint
,projectID
, andAPI key
based on values from thereq.variables
object. - It creates a new instance of the
**sdk.Databases**
using the client. - Finally, it uses the
createDocument()
method to create a new document in the Appwrite database. The document data is based on the message object created earlier.
- If the incoming request method is
- After successfully creating the document, the function returns an
HTTP
response with the text "Message sent." - If the request method is neither
GET
norPOST
or the content type is not 'application/x-www-form-urlencoded', then the function returns an HTTP response with the text "Not Found" and a status code of 404.
Deploying the Appwrite Function 1.3
To deploy the Appwrite function, run the command below:
appwrite deploy function
Executing the above command will require you to pick the appropriate function you want to deploy. Upon successful deployment, you will get a message like the one below in your terminal.
✓ Success Deployed <function-name> ( functionID)
Migrating to Appwrite Functions 1.4
On the left side of the Appwrite Cloud dashboard, click on the Templates tab to create a starter function.
Clicking on the Create function button will take you to the tab where you can start your configuration, like this.
The next thing you should do is create the variable, and here is where you will paste the API KEY
you created earlier.
Then, Connect to your repository by choosing either “Create a new repository” or “Add to existing repository” (in this case, you are connecting with the existing Next.js repository).
Next, choose the GitHub repository to trigger the Appwrite function.
Now, you should complete your configuration by configuring the Git production branch and clicking on Create.
NOTE: The CLI deployment is still available, but Git deployment is preferable.
After completing the configurations, you should have an active Function deployed like this.
Completing the above configuration will create a new Appwrite function src/main.js
file in your repository.
Next, navigate to the Domains tab from the Functions page and copy the verified generated URL.
Appwrite Functions 1.4 logic
Following the exact function implementation from the Function version 1.3 above—but this time in Appwrite 1.4—navigate to src/main.js
and paste the code below:
import { Client, Databases, ID } from "node-appwrite";
import querystring from "node:querystring";
export default async ({ req, res, log, error }) => {
// You can log messages to the console
log("Hello, Logs!");
// If something goes wrong, log an error
error("Hello, Errors!");
if (req.method === "GET") {
return res.send(html, 200, { "content-type": "text/html" });
}
if (
req.method === "POST" &&
req.headers["content-type"] === "application/x-www-form-urlencoded"
) {
const formData = querystring.parse(req.body);
const message = {
name: formData.name,
email: formData.email,
date: formData.date,
time: formData.time,
content: formData.content,
};
const client = new Client();
client
.setEndpoint("https://cloud.appwrite.io/v1")
.setProject(process.env.APPWRITE_FUNCTION_PROJECT_ID)
.setKey(process.env.APPWRITE_API_KEY);
const databases = new Databases(client);
const document = await databases.createDocument(
"650efb16ae5ebb92185a",
"650efb593f6c9f97c09c",
ID.unique(),
message
);
return res.send("Message sent");
}
return res.send("Not found", 404);
};
These are what changed in the above code compared to version 1.3:
- The parameter passed into functions has changed.
req
andres
have been replaced by thecontext
object. - To improve privacy and logging reliability, new
context.log()
andcontext.error()
functions were provided. - The old way of
req.variables
has been deprecated; variables are now passed into each function as environment variables. - Some information, like triggers and events, are now passed in as headers instead of variables.
- The
req
object has been updated to use terminology consistent with typical HTTP concepts, which include familiar concepts like headers, body, HTTP methods, and others. - By default, the request and response information is not logged. This is to protect user information by default.
- A response such as
context.res.send("")
is returned. This prevents confusing errors when functions are terminated prematurely before a response is sent.
By now, the application should look like this:
https://www.loom.com/share/570cb616f33241e5b9a334057bcd4471?sid=0d91fbb4-e1c0-43dd-aa2b-3858b1dc9bc3
The Appwrite Cloud Functions Execution completed a new Function like this:
And the Appwrite Cloud Databases updated the database collection like this:
Conclusion
This article discussed how to migrate to Appwrite Functions 1.4 and implement them in a Next.js application. This article also provided a detailed and easy guide on creating an Appwrite Cloud project and utilizing the amazing features and the revised syntax of the Appwrite Functions 1.4.
Resources
Here are some additional resources that might be helpful: