Appwrites Health Service
Tags: javascript, appwrite, beginners, hacktoberfest
Published: 2021-10-27 16:51:11

##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](https://github.com/fernandoamz/node-express-server-rest-api) 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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0xlgvlfk3zf582h4x3m6.gif)
 
__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.

```javascript
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,
}
```


__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: 

```javascript
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)
})

```

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.

```javascript
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)
    });
  });
}
```

##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](https://github.com/fernandoamz/node-express-server-rest-api)

##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.