DEV Community 👩‍💻👨‍💻

Finn Kranzosch
Finn Kranzosch

Posted on

Node.JS in Appwrite

Introduction

The following article covers the use of the Appwrite Node.JS SDK to develop Appwrite Functions. Appwrite Functions are used to extend the Appwrite Server functionality by providing various options for using custom code. Several different runtimes can be used for this purpose. In the following, the Node.JS runtime will be discussed. Developed and provided Appwrite Functions can be executed manually, based on a CRON schedule or as a reaction to system events.

Project Creation

Functions are bound to a specific project. To illustrate the various functionalities within this article, a sample project will be created.

In the Appwrite console (Installation of Appwrite):
Project Creation in Appwrite Console

The project created in this way still needs a Database Collection for the examples, which can be created under Database > Add Collection:
Creation of Collection

This collection should have the following rules:
Collection Rules

API Key

To access the different functionalities of Appwrite within an Appwrite function, a so-called API Key is required. This can be created in the Appwrite console under API Keys > Add API Key and should have the permissions documents.write and functions.write for the following example.

The Function

Before the function can be created the Node.JS SDK must be installed with npm install node-appwrite. Afterwards the function itself can be created. This does not yet contain any code. The code is then created and added to the Appwrite Function in the form of a so-called tag.

Function Creation

The creation of the Appwrite Function can also be done through the Node.JS SDK, just like the later code. To do this, a new file is created (for example, create_function.js) that contains the following code:

Initialize the SDK:

const appwrite = require("node-appwrite");

const client = new appwrite.Client();

const functions = new appwrite.Functions(client);

client
    .setEndpoint('[APPWRITE-API-ENDPOINT]')
    .setProject('[APPWRITE-PROJECT-ID]')
    .setKey('[APPWRITE-API-KEY]')
;
Enter fullscreen mode Exit fullscreen mode

The [APPWRITE-API-ENDPOINT], [APPWRITE-PROJECT-ID] and [APPWRITE-API-KEY] values must be adjusted to suit the environment.

Creating the function:

let promise =
    functions.create(
        'Create Filename', [], 'node-16.0',
        {
            'SONGS_COLLECTION': '[SONGS-COLECTION-ID]',
            'APPWRITE_ENDPOINT': '[APPWRITE-API-ENDPOINT]',
            'APPWRITE_PROJECT_ID': '[APPWRITE-PROJECT-ID]',
            'APPWRITE_API_KEY': '[APPWRITE-API-KEY]',
        },
        ['database.documents.create', 'database.documents.update'])
;

promise.then( response => {
    console.log(response);  // Success
}, error => {
    console.error(error);   // Failure
});
Enter fullscreen mode Exit fullscreen mode

The values [APPWRITE-API-ENDPOINT], [APPWRITE-PROJECT-ID], [APPWRITE-API-KEY] and [SONGS-COLLECTION-ID] must be adapted to the environment. The ID of the songs collection can be read in the collection settings. Since the Appwrite Functions run in a Docker container, http://localhost/v1 cannot be used for [APPWRITE-API-ENDPOINT]. Here, either the appropriate domain or the IP address of the host system must be used in a local setup.

The function functions.create() gets 5 parameters. The first parameter specifies the name of the function. The second one specifies if and if so which users or user roles have the execute permission. The third specifies the runtime to be used. The fourth parameter contains the later needed environment variables and the fifth parameter specifies the events at which the function should be executed. Now the file can be executed with node create_function.js and thus the Appwrite Function can be created. In the Functions section of the Appwrite console a new function should now have been created.

The pure creation of a function can also be done via the graphical interface of the Appwrite console under Functions > Add Function.

The Function Itself

The code of the Appwrite Function is first created locally and then uploaded together with the required dependencies as a tag of the corresponding Appwrite Function. The following sample code is to enter the filename of the song into the designated rule each time a document of the Songs Collection is created or updated.

To do this, the file index.js is created with the following content.

Check whether the created or updated document belongs to the Songs Collection:

const DATA = JSON.parse(process.env.APPWRITE_FUNCTION_EVENT_DATA);
const SONGS_COLLECTION = process.env.SONGS_COLLECTION;

const { $id, $collection, title, artist } = DATA;

// Stop if it's not the Songs Collection
if ($collection !== SONGS_COLLECTION) {
    return;
}
Enter fullscreen mode Exit fullscreen mode

Initialize the SDK:

const appwrite = require("node-appwrite");
const client = new appwrite.Client();
const database = new appwrite.Database(client);

client
    .setEndpoint(process.env.APPWRITE_ENDPOINT)
    .setProject(process.env.APPWRITE_PROJECT_ID)
    .setKey(process.env.APPWRITE_API_KEY)
;
Enter fullscreen mode Exit fullscreen mode

To prevent a continuous loop, a check is made to ensure that the song does not already have the correct filename:

// Create filename string
let filename = title + " - " + artist + ".mp3";

// Stop if the filename is already correct
if (filename === DATA.filename) {
    return;
}
Enter fullscreen mode Exit fullscreen mode

Adapting the Song Document:

let promise = database.updateDocument($collection, $id, { filename: filename });

promise.then( response => {
    console.log("Filename changed successfully");
    console.log(response);
}, error => {
    console.error(error);
});
Enter fullscreen mode Exit fullscreen mode

To add this code as a tag to the Appwrite Function, the file index.js must first be packed together with the dependencies. To do this, the command tar -zcvf code.tar.gz . is executed in the same directory as the file and the node_modules folder. Then another file create_tag.js is created which handles the upload of the tag. It contains the following code.

Initialize the SDK:

const appwrite = require('node-appwrite');
const fs = require('fs');

const client = new appwrite.Client();

const functions = new appwrite.Functions(client);

client
    .setEndpoint('[APPWRITE-API-ENDPOINT]')
    .setProject('[APPWRITE-PROJECT-ID]')
    .setKey('[APPWRITE-API-KEY]')
;
Enter fullscreen mode Exit fullscreen mode

Again, the [APPWRITE-API-ENDPOINT], [APPWRITE-PROJECT-ID] and [APPWRITE-API-KEY] values must be adjusted accordingly.

Upload the tag:

let promise =
    functions.createTag(
        '[FUNCTION-ID]', 'node index.js', fs.createReadStream(__dirname + '/code.tar.gz')
    )
;

promise.then( response => {
    console.log(response);
}, error => {
    console.error(error);
});
Enter fullscreen mode Exit fullscreen mode

The value for [FUNCTION-ID] must be adjusted accordingly. The ID of the Appwrite Function can be read in the settings of the function in the Appwrite console.

By executing node create_tag.js the tag of the Appwrite Function is added.

Activating and testing the Appwrite Function

The just uploaded tag must be activated in the Appwrite console under Functions > Settings of the corresponding function > Activate.

To test the function, a new song can be added to the Songs Collection in the Appwrite console. After a short time the filename should have been adjusted automatically.

Create Song

New Filename

Further Information

The article covered the basics of creating and using Appwrite Functions with the Node.JS SDK. This example ist just a fraction of what Appwrite Functions can do. More in-depth information can be found here:

Top comments (0)

Here is a post you might want to check out:

Regex for lazy developers

regex for lazy devs

Sorry for the callout 😆