DEV Community 👩‍💻👨‍💻

Fernando Amezcua
Fernando Amezcua

Posted on • Updated on

Appwrites Health Service

Overview

The Health service is designed to allow you to both validate and monitor that your Appwrite server instance and all of its internal components are up and responsive.

Here, we are going to talk about how to use these services running on React Native in order to give a better idea about how we can implement in our own way.

Please, clone this dummy express api repository and install dependencies to follow this example.

Getting Started

We are going to work with two branches for this example.

QUICK NOTE

  • develop here, we have all the dummy example to follow this tutorial

  • appwrite-health-system, This branch contains all the complete example in case that you want to take a look to the complete example.

go ahead

1. Install dependency
We are going to need install the package from appwrite core team:

npm install node-appwrite --save

2. Create SDK file
Create a new file src/config/index.js, this file will help us to create a connection between our express app and appwrite service.

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

// Init SDK
let client = new sdk.Client();
let health = new sdk.Health(client);

client
  .setEndpoint('http://localhost/v1')
  .setProject('PROJECT_ID')
  .setKey('YOUR_API_KEY');

export {
  health,
  client,
}
Enter fullscreen mode Exit fullscreen mode

3. Server file
For this we need install a bunch of packages, here I let you the command:

npm install compression router body-parser --save

Follow me to improve the server:

const compression   = require('compression')
const express       = require('express')
const app           = express()
const router        = express.Router()
const bodyParser    = require("body-parser")

app.use(compression())
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({
    extended: true
}))

app.disable('x-powered-by')
app.use(function(req, res, next){
    res.setHeader("Access-Control-Allow-Origin", "*");
    res.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    next()
})

router.use(function(req, res, next){
    console.log("[ API ] -> /" + req.method + ' -> ' + req.path)
    next()
})

const system_health = require('./routes/systemHealth')(router);

const port = process.env.PORT || 3000
app.use("/api", router)

app.use("*", function(req, res){
    res.status(404).json({status: 'ERROR', result: '404'})
})

app.listen(port, function(){
  console.log('[ API ] -> Server Ready: ' + port)
})

Enter fullscreen mode Exit fullscreen mode

As we can see, now, we have a complete server for just add the routes. come on to the src/routes/systemHealth.js, on this file we need to create the logic for every route.

On the code's comments I will let you a little explanation that I got from the official documentation, in order that you identify the different cases.

const {
  client,
  health,  
} = require('../config')

module.exports = function (router){

  //* Check the Appwrite HTTP server is up and responsive.
  // This route is used to overview check the health of the system
  router.get('/health', (req, res, next) => {
    // This line contains the system modules that are being checked
    // It will be changed on every route
    let promise = health.get();

    promise.then(function (response) {
      res.json(response);
    }, function (error) {
      res.json(error)
    });
  });

  //* Check the Appwrite database server is up and connection is successful.
  router.get('/health/db', (req, res, next) => {
    let promise = health.getDB();

    promise.then(function (response) {
      res.json(response);
    }, function (error) {
      res.json(error)
    });
  });

  //* Check the Appwrite in-memory cache server is up and connection is successful.
  router.get('/health/cache', (req, res, next) => {
    let promise = health.getCache();

    promise.then(function (response) {
      res.json(response);
    }, function (error) {
      res.json(error)
    });
  });

  /*
    Check the Appwrite server time is synced with Google remote NTP server.
    We use this technology to smoothly handle leap seconds with no disruptive events.
    The Network Time Protocol (NTP) is used by hundreds of millions of computers and devices to synchronize their clocks over the Internet.
    If your computer sets its own clock, it likely uses NTP.
  */
  router.get('/health/time', (req, res, next) => {
    let promise = health.getTime();

    promise.then(function (response) {
      res.json(response);
    }, function (error) {
      res.json(error)
    });
  });

  //* Get the number of webhooks that are waiting to be processed in the Appwrite internal queue server
  router.get('/health/webhooks', (req, res, next) => {
    let promise = health.getQueueWebhooks();

    promise.then(function (response) {
      res.json(response);
    }, function (error) {
      res.json(error)
    });
  });

  //* Get the number of tasks that are waiting to be processed in the Appwrite internal queue server.
  router.get('/health/queue/tasks', (req, res, next) => {
    let promise = health.getQueueWebhooks();

    promise.then(function (response) {
      res.json(response);
    }, function (error) {
      res.json(error)
    });
  });

  //* Get the number of logs that are waiting to be processed in the Appwrite internal queue server.
  router.get('/health/queue/logs', (req, res, next) => {
    let promise = health.getQueueLogs();

    promise.then(function (response) {
      res.json(response);
    }, function (error) {
      res.json(error)
    });
  });

  //* Get the number of usage stats that are waiting to be processed in the Appwrite internal queue server.
  router.get('/health/queue/usage', (req, res, next) => {
    let promise = health.getQueueUsage();

    promise.then(function (response) {
      res.json(response);
    }, function (error) {
      res.json(error)
    });
  });

  //* Get the number of certificates that are waiting to be issued against Letsencrypt in the Appwrite internal queue server.
  router.get('/health/queue/certificates', (req, res, next) => {
    let promise = health.getQueueCertificates();

    promise.then(function (response) {
      res.json(response);
    }, function (error) {
      res.json(error)
    });
  });

  //* To access this route, init your SDK with your project unique ID and API Key secret token. Make sure your API Key is granted with access to the "health.read" permission scope.
  router.get('/health/queue/functions', (req, res, next) => {
    let promise = health.getQueueFunctions();

    promise.then(function (response) {
      res.json(response);
    }, function (error) {
      res.json(error)
    });
  });

  //* Check the Appwrite local storage device is up and connection is successful.
  router.get('/health/storage/local', (req, res, next) => {
    let promise = health.getStorageLocal();

    promise.then(function (response) {
      res.json(response);
    }, function (error) {
      res.json(error)
    });
  });

  //* Check the Appwrite Anti Virus server is up and connection is successful.
  router.get('/health/anti-virus', (req, res, next) => {
    let promise = health.getStorageLocal();

    promise.then(function (response) {
      res.json(response);
    }, function (error) {
      res.json(error)
    });
  });
}
Enter fullscreen mode Exit fullscreen mode

Summary

Now, you have a server to monitor all the services and if them are working good, this is very helpful. This kind of monitors help us to find faster solutions in our app. This hacktoberfest I've been touching Appwrite and I can say that is a tool that you should take a look as developer. Thank so much for read this little blogspot.

Full complete example

Next Steps

  • Create test files with chai.
  • Write a dictionary with all responses returned in every route.
  • Explain how to deploy it on a cloud service.

Top comments (1)

Visualizing Promises and Async/Await 🤯

async await

☝️ Check out this all-time classic DEV post