HTTP

Now that we have data from XDK (see more about it in C) we need to have a way to save it in a database and actually to can use it in some applications, having this in mind, we are going to build a powerful RESTful API using nodeJS, Hapi.js, and mongoDB.

Prerequisites

  • NodeJS and NPM installed

  • Basic JavaScript 

  • Terminal (any will do, preferably bash-based)

  • Text editor (any will do)

  • MongoDB (further information here)

So we are going to start initializing a npm package, and install all dependencies that we'll use...

$ mkdir XDK-server
$ cd XDK-server
$ npm init
$ npm install nodemon hapi mongoose request

request

mongoose

Nodemon

hapi.js

Will help us to use http verbs inside our server

Will help us to query our database

Will help us to can hot reload our server just saving

Will help us as the selected framework to build a server with nodeJS

Basically its all we need for our server, after this we are going to create the following model:

  • Models

    • xdk_virtualsensors.js

  • Routes

    • routes.js

    • xdk.js

  • index.js

First of all we need to create our index.js, define our port, initialize plugins, and connect to database.

index.js
'use strict'


const Hapi = require('hapi');
const mongoose = require('mongoose');
const mongoDbUri = 'mongodb://localhost:27017/XDK_db'; //Change name database
const routes = require('./routes/routes')
const server = Hapi.server({
    port: 3000,
    routes: {
        cors: {
            origin: ["*"], //Accept petitions from all
            credentials: true
        }
    },    
})

//Requires plugins and initializing server
const init = async () => {
    await server.register([
        { plugin: require('hapi-require-https') }
    ])

    await server.start()
    
    //Connect with mongoDB
    mongoose.connect(mongoDbUri).then(() =>{
            console.log('App is connected to mongo')
        }, err => {
        console.log(err)
    })
    console.log('Server started on port', server.info.port)
}

//Add routes for a better organization for our server
server.route(routes)

//Example
server.route({
    path: '/',
    method: 'GET',
    handler: (req, h) =>  {
        return 'XDK API'
    }
});

//Unhandled
process.on('unhandledRejection', (err) => {
    console.log(err)
    process.exit()
})

init()

In this case I already have a local database where I am saving my data. Its not difficult to install mongoDB and use it, but if you don't know how to do it look at this link MongoDB.

In Models we are going to define our schema using mongoose tool called "schema", basically is just define what we are going to add to our database, and what kind of parameters this schema is going to have such as type of variable to add, if one variable is required or not, etc.

the schema for xdk_virtualsensors is the following:

xdk_virtualsensors.js
const mongoose = require('mongoos
e')
const Schema = mongoose.Schema

const virtualSensors = new Schema ({
    name: {
        type: String,
        minlength: 2,
        maxlength: 30
    },
    timestamp: {
        type: Date,
    },
    quatW: {
        type: Number,
    },
    quatX: {
        type: Number,
    },
    quatY: {
        type: Number,
    },
    quatZ: {
        type: Number,
    },
});

module.exports = mongoose.model('virtualSensors', virtualSensors, 'virtualSensors');

after this we need to define our routes in routes.js / xdk.js. Basically we'll put what routes are available and in the server side what to do when some routes is reached. what we are going to build is a CRUD API.

In this part is important to see how mongoose works in its documentation because mongoose is the tool that we are going to use for query database, its pretty simple to use it but for further information check it out here --> mongoose.

Here is the code that we are going to use for GET data in real time, I already have code for GET data from timestamps, delete data, and create data from XDK firmware code. For easier understanding we are just going to use the part where we add our data to mongoDB and where we ask for the data from frontend.

const mongoose = require('mongoose')
const Xdk = require('../models/xdk')
const virtualSensors = require('../models/xdk_virtualsensors')

module.exports = [
//Create document in mongoDB from XDK  
    { //POST /xdk/virtualsensors
    method: 'POST',
    path: '/xdk/{name}/virtualsensors',
    handler: async (request, h) => {
    
        const virtualsensors = {
            timestamp: Date.now(),
            name: request.params.name,
            quatW: parseFloat(request.payload.w),
            quatX: parseFloat(request.payload.x),
            quatY: parseFloat(request.payload.y),
            quatZ: parseFloat(request.payload.z)
        }

        return virtualSensors.create(virtualsensors).then((response) => {
            return h.response({
                success: true,
                response: {
                    message: 'Successfully created'
                }
            }).code(200)
        }).catch((err) => {
            console.log(`error ${err}`)
            return h.response({
                success: false,
                response: 'TRY AGAIN'
            })
        })
    }
    },
    
//GET data from Frontend in this case is the last data that we just stored
    { //GET /xdk/sensors
        method: 'GET',
        path: '/xdk/virtualsensors/{name}',
        handler: async (request, h) => {
        
            let sensors = await virtualSensors.find().limit(1).sort({ "_id": -1 }).exec()

            if (sensors) {
                return h.response({
                    success: true,
                    response: {
                        message: "Succesfully find it",
                        sensors: sensors
                    }
                })
            } else {
                return h.response({
                    success: false,
                    response: "Not found"
                })
            }
        }
    }
]

Thats all what we need for using this backend if you want you can download my code that is in my github account ---> https://github.com/BrandonEscamilla/FlighComputer-BE

For use it just copy the following steps in your terminal...

$ mkdir newProject
$ cd newProject
$ git clone https://github.com/BrandonEscamilla/FlighComputer-BE.git
$ npm install
$ nodemon index.js

Of course you need to configure your database path, and your own routes if you want, it could works as a boilerplate for your own project, Enjoy it!

API DOCUMENTATION

GET XDK DATA

GET http://localhost:3000/xdk/virtualsensors/{name}

Get last XDK data stored in mongoDB using mongoose.

Path Parameters

NameTypeDescription

string

Name of XDK (for have a better organization and know who is creating or getting data.) And actually you can make restriction about who is getting data.

success: true,
response: {
    message: "Succesfully find it",
    sensors: { 
        name: "brandonxdk"
        quatW: 0.99
        quatX: -0.04
        quatY: 0.1
        quatZ: -0.04
        timestamp: "2018-12-27T00:08:57.226Z"
        __v: 0
        _id: "5c241819aeb3c317ececd00f"
    }
}

ADD XDK DATA

POST http://localhost:3000/xdk/{name}/virtualsensors

Add XDK data to mongoDB in real time.

Path Parameters

NameTypeDescription

string

Name of XDK (for have a better organization and know who is creating or getting data.) And actually you can make restriction about who is getting data.

success: true,
response: {
    message: 'Successfully created'
}

Github Source Code

Find my source code here!

Last updated