Skip to content

Tutorials 

edgeEngine Serverless APIs

What does serverless mean?

Traditional backend development requires developers to think about how to scale, maintain and operate a server. To simplify the process, mimik provides a serverless environment for edge microservices to use at runtime. edgeEngine takes care of deployment and all concerns related to servers. Developers only need to design the processing of HTTP requests and responses. That is why it is called serverless programming.

This is the serverless context. The purpose of the context object is to provide properties for processing HTTP requests.
Programming Model

To start with, you supply a callback function and assign it to mimikModule.exports. The callback function must have the following arguments:

 

context               request               response

 

These arguments give you full control over HTTP requests and responses. The context argument passes mimik’s serverless programming environment.

Example Code
mimik Technology is offering a unique solution to Smart Car use case. Our solution is focused on hybrid utilization of centralized cloud and edge cloud using mimik edge Cloud Engine. We at mimik believe that instead of having all the communications from an end user on the cloud (where it can be any device such as a cellphone or a smart car) to the centralized cloud and back, we can have a hybrid system that leverages potentials of edge cloud engines in order to have a faster, safe, and more suitable solutions to real world problems
import Router from 'router';

const app = Router({ mergeParams: true });

mimikModule.exports = (context, request, response) => {
  global.context = context;
  app(request, response, (e) => {
    request.end(JSON.stringify({ code: e ? 400 : 404, message: e || 'Not Found' }));
  });
};

app.get('/', (request, response) => {
  response.end('Hello World!');
});

context

Description
This is the serverless context. The purpose of the context object is to provide properties for processing HTTP requests.
Type

object

Property
Type
Description
env
object
This object contains environment variables passed on to a container on initialization.
storage
object
Please refer to the documentation below on storage APIs.
http
object
Please refer to the documentation below on http client APIs.
edge
object
Please refer to the documentation below on edge APIs.
request
Description
This object represents the HTTP request made by the client to the server. This request object follows very closely to the nodejs HTTP server request object.
Type

object

Property
Type
Description
url
string
The url of the request.
method
string
The HTTP method of the request, such as GET, POST, DELETE, PUT, etc.
authorization
string
The HTTP header, such as the Authorization Header.
body
string
If the content-type is application/json of the client, this will be the body of the POST or PUT request.
handleFormRequest
function
This function is used to handle HTTP POST with content type ‘multipart/form-data’. The function takes an object formRequestOption from the developer to generate a list of required callbacks. See below for more detail.
request.handleFormRequest(formRequestOption)
Type
function
Arguments
Argument
Type
Description
formRequestOption
object
This object passes the callback function required by request.handleFormRequest() to handle the HTTP Form POST.
Example Code
app.post('/form', (request, response) => {
    const metadata = "";
    const file = {};
    req.handleFormRequest({
        found: (key, filename) => {
            let formRequestToDo = {
                action: 'skip'
            };
            if (key === 'metadata') {
                formRequestToDo = {
                    action: 'get'
                };
            } else if (key === 'file') {
                file.filename = filename;
                formRequestToDo = {
                    action: 'store',
                    path: 'new-filename'
                };
            } else {
                formRequestToDo = {
                    action: 'abort'
                }
            }
            return formRequestToDo ;
        },
        get: (key, value) => {
            metadataBuf = metadata.concat(value);
        },
        store: (path, size) => {
            file.path = path;
            file.size = size;
        },
    });
    response.end(value);
});
formRequestOption
Description

This object passes the required function required by request.handleFormRequest() to handle the HTTP Form POST.

Type

object

Property
Type
Description
found
function
This function callback is called whenever a new key is encountered. You must return a formRequestToDo to indicate what to do with the key. Please refer to formRequestToDo.action and formRequestToDo.path.
get
function
This function callback is called when you indicate the method to get the data using a key. The value of the key is returned as a string.
store
function
This function callback is called when you indicate the method to store data with a specific path.
formRequestOption.found(key, filename)
Type
function
Arguments
Argument
Type
Description
key
string
The key of the form element.
filename
string
The name of the file to store.
Example
app.post('/form', (request, response) => {
    const metadata = "";
    const file = {};
    req.handleFormRequest({
        found: (key, filename) => {
           if (key === 'file') {
                file.filename = filename;
                formRequestToDo = {
                    action: 'store',
                    path: 'new-filename'
                };
            }
            return formRequestToDo ;
        }
    });
    response.end(value);
});
formRequestOption.found(key, filename)
Type
function
Arguments
Argument
Type
Description
key
string
The key of the form element.
filename
string
The value of the form element corresponding to the key.
Example Code
app.post('/form', (request, response) => {
    const metadata = "";
    const file = {};
    req.handleFormRequest({
        get: (key, value) => {
            metadataBuf = metadata.concat(value);
        }
    });
    response.end(value);
});
formRequestOption.store(path, size)
Type
function
Arguments
Argument
Type
Description
path
string
The file path of the form element to store.
size
string
The value of the form element corresponding to the key.
Example Code
app.post('/form', (request, response) => {
    const metadata = "";
    const file = {};
    req.handleFormRequest({
        store: (path, size) => {
            file.path = path;
            file.size = size;
        }
    });
    response.end(value);
});
formRequestToDo
Description
This object passes a list that is a required callback function to the request.handleFormRequest() to handle the ‘HTTP Form POST’.
Type

object

Property
Type
Description
action
string
The following actions are available:
· abort: this will abort the entire form request.
· skip: this will skip the current key of the form request.
· store: this will handle the form request using the store function provided in formRequestOption.
· get: this will handle the form request using the get function provided in formRequestOption.
path
string
If formRequestToDo.action is store, one needs to know where to store the file. formRequestToDo.path is the path of the file.
response  
Description

This class represents the server HTTP response object, similar to a Express.js HTTP server response object.

Type

object

Property
Type
Description
statusCode
integer
The HTTP response code. the default is 200.
end
function
Send back the response in string.
writeMimeFile
function
Send back the response as mime file.
response.end(body)
Type

function

Arguments
Argument
Type
Description
body
string
The response body, which must be a string.
Example Code
app.get('/', (request, response) => {
    response.statusCode = 200;
    response.end('<h1>Hello World!</h1>');
});
response.writeMimeFile(filePath, mimeType)
Type

function

Arguments
Argument
Type
Description
filePath
string
The path of the file that response.writeMimeFile() wants to return
mimeType
string
The file type of the return file. The default is application/json
Example Code
app.get('/', (request, response) => {
    response.statusCode = 200;
    const filePath = '/home/usr/example.jpeg';
    response.writeMimeFile(filepath, 'image/jpeg');
});
storage
Description

In order for an edge microservice to store something on a device, mimik provides a light-weight key-value database based on  SQLite.

Type

object

Property
Type
Description
getItem
function
This function gets the data from the database by querying using the data’s key.
setItem
function
This function sets the value of the data using a key in the database.
eachItem
function
This function iterates through the database and makes a callback for each database record.
removeItem
function
This function removes a data entry from the database using its key.
saveFile
function
This function iterates through the database and makes a callback for each database record.
deleteFile
function
This function deletes the file with corresponding filename.
context.storage.getItem(key)
Type

function

Arguments
Argument
Type
Description
key
string
Get value from the database by querying using a key.
Return Type

string

Example Code
app.get('/', (request, response) => {
    const value = context.storage.getItem('key');
    response.end(value);
});
context.storage.setItem(key, value)
Type

function

Arguments
Argument
Type
Description
key
string
Get a value from the database by querying using its key.
value
string
Set a value in the database using its key.
Example Code
app.post('/form', (request, response) => {
    const { name } = JSON.parse(request.body);
    context.storage.setItem('name', name);
    response.end('value stored successfully.');
});
context.storage.eachItem(callback(key, value))
Type

function

Arguments
Argument
Type
Description
callback(key, value)
function
A callback for handling each item in a database with the given key and value.
Example Code
app.get('/', (request, response) => {
    context.storage.eachItem((key, value) => {
          // do something....
    });
    response.end('done');
});
context.storage.removeItem(key)
Type

function

Arguments
Argument
Type
Description
key
string
Remove an item from a database using its key.
Example Code
app.delete('/form', (request, response) => {
    context.storage.removeItem('name');
    response.end('item remove successfully.');
});
context.storage.saveFile(fileName, base64EncodedString)
Type

function

Arguments
Argument
Type
Description
fileName
string
The name of the file.
base64EncodedString
string
Save a file in a database with its base64Encoded binary data.
Example Code
app.post('/file', (request, response) => {
    const base64 = '..........';
    const fileName = 'base64.jpeg';
    context.storage.saveFile(fileName, base64);
    response.end('item save successfully.');
});
context.storage.deleteFile(fileName)
Type

function

Arguments
Argument
Type
Description
fileName
string
The name of the file.
base64EncodedString
string
Delete the file’s base64Encoded binary data.
Example Code
app.delete('/file', (request, response) => {
    const fileName = 'base64.jpeg';
    context.storage.deleteFile(fileName);
    response.end('item delete successfully.');
});
http
Description

In order for an edge microservice to make a HTTP request to another edge microservice or mimik’s backend, mimik provides a built-in HTTP request client for HTTP communication.

Type

object

Property
Type
Description
request
function
This function takes the httpClientOption and parses it as an instance of a HTTP client interface.
context.http.request(httpClientOption)
Type

function

Arguments
Property
Type
Description
httpClientOption
object
These are the available HTTP request configuration options for making requests within the edge microservice context.
Example Code
app.post('/data', (request, response) => {
    context.http.request(({
        type: 'POST',
        data: '{}',
        url: 'http://www.example.com/data',
        authorization: 'Bearer token',
        success: (result) => {
            response.end(result.data);
        },
        error: (err) => {
            console.log(err);
        }
    }));
});
httpClientOption  
Description
These are the available HTTP request configuration options for making requests within the edge microservice context.
Type

object

Property
Type
Description
type
string
The HTTP method of the request, such as GET, POST, DELETE, PUT etc.
data
string
If the HTTP method is POST or PUT or PATCH, the data is the body of the method.
url
string
The URL of the HTTP request.
authorization
string
The HTTP authorization header of the request.
success
function
This is the success callback function.
error
function
This is the error callback function.
httpClientOption.success(result)
Type

function

Arguments
Argument
Type
Description
result
string
Parses the result of the HTTP request to the callback function.
Example Code
app.get('/data', (request, response) => {
    context.http.request(({
        type: 'get',
        data: '{}',
        url: 'http://www.example.com/data',
        authorization: 'Bearer token',
        success: (result) => {
            response.end(result.data);
        }
    }));
});
httpClientOption.error(result)
Type

function

Arguments
Argument
Type
Description
error
string
Parses the error of HTTP request to the callback function
app.get('/ping', (request, response) => {
    context.http.request(({
        type: 'get',
        data: '{}',
        url: 'http://www.example.com/ping',
        authorization: '',
        error: (error) => {
            response.end('Website is offline!');
        }
    }));
});
edge
Description

In order for an edge node to securely receive sensitive information about the cluster and back-end tunneling information, mimik provides functions to decrypt the encrypted messages and making requests to the back-end to create a private tunnel (which is a BEP).

Type

object

Property
Type
Description
decryptEncryptedNodesJson
function
This function decrypts the sensitive information about cluster and cloud backend receive by the edgeEngine from other edge nodes.
requestBep
function
This function will request a BEP tunnel from edgeEngine. If a BEP has not already been created, this will create a new BEP. If a BEP has already been created, this will just return the existing BEP.
context.edge.decryptEncryptedNodesJson(decryptNodesOption)
Type

function

Arguments
Argument
Type
Description
decryptNodesOption
object
These are the available decrypting node message configuration options for extracting sensitive information from clusters.
Example Code
app.get('/localDevices', (request, response) => {
    context.http.request(({
        url: `http://127.0.0.1:8083/mds/v1/nodes?clusters=linkLocal`,
        success: (result) => {
            const nodes = JSON.parse(result.data);
            const data = JSON.stringify(nodes.data);
            context.edge.decryptEncryptedNodesJson({
                type: 'local',
                data: encryptedJson,
                success: (result) => {
                    response.end(result.data);
                },
                error: (err) => {
                    console.log(err.message);
                }
            });
        },
        error: (err) => {
            console.log(err.message);
        }
    }));
});
context.edge.requestBep(requestBepOption)
Type

function

Arguments
Argument
Type
Description
requestBepOption
object
These are the available BEP request configuration options for receiving a private communication tunnel.
app.get('/localDevices', (request, response) => {
    context.edge.requestBep({
        success: (result) => {
            console.log(result.data);
        },
        error: (err) => {
            console.log(new Error(err.message));
        }
    });
    // ...
});
decryptNodesOption  
Description

These are the available decrypting node message configuration options for extracting sensitive information from clusters.

Type

object

Property
Type
Description
type
string
The type indicates that the data to decode is either ‘account’ or ‘local’. If the data is obtained from an account cluster, one should use ‘account’. Anything else should use ‘local’.
token
string
The edge token that you obtained through mimik’s OpenID.
data
string
The data JSON that you got from the GET /nodes that you would like to decode.
success
function
This is the success callback function.
error
function
This is the error callback function.
decryptNodesOption.success(result)
Type

function

Arguments
Argument
Type
Description
result
string
Parses the result of decryption to the callback function.
Example Code
app.get('/localDevices', (request, response) => {
      context.http.request(({
        url: 'http://127.0.0.1:8083/mds/v1/nodes?clusters=linkLocal',
        success: function(r) {
          if (!request.authorization) {
            response.status = 403;
            response.end(JSON.stringify({ 'msg': 'missing bearer token' }, 2, null));
            return;
          }
          const authorization = request.authorization.split(' ');
          if (authorization.length < 2) {
            response.status = 403;
            response.end(JSON.stringify({ 'msg': 'missing bearer token' }, 2, null));
            return;
          }
          const token = authorization[1];
          const nodes = JSON.parse(r.data);
          const data = JSON.stringify(nodes.data);

          context.edge.decryptEncryptedNodesJson({
            type: 'local',
            data,
            token,
            success: function(result) { // success option
              response.end(JSON.stringify(JSON.parse(result.data), null, 2));
            },
            error: function(err) {
              response.end(err.message);
            }
          });
        },
        error: function(err) {
          response.end(err.message);
        }
      }));
    });
decryptNodesOption.error(result)
Type

function

Arguments
Argument
Type
Description
error
string
Parses the error of decryption to the callback function.
Example Code
app.get('/localDevices', (request, response) => {
      context.http.request(({
        url: 'http://127.0.0.1:8083/mds/v1/nodes?clusters=linkLocal',
        success: function(r) {
          if (!request.authorization) {
            response.status = 403;
            response.end(JSON.stringify({ 'msg': 'missing bearer token' }, 2, null));
            return;
          }
          const authorization = request.authorization.split(' ');
          if (authorization.length < 2) {
            response.status = 403;
            response.end(JSON.stringify({ 'msg': 'missing bearer token' }, 2, null));
            return;
          }
          const token = authorization[1];
          const nodes = JSON.parse(r.data);
          const data = JSON.stringify(nodes.data);

          context.edge.decryptEncryptedNodesJson({
            type: 'local',
            data,
            token,
            success: function(result) {
              response.end(JSON.stringify(JSON.parse(result.data), null, 2));
            },
            error: function(err) { // error option
              response.end(err.message);
            }
          });
        },
        error: function(err) {
          response.end(err.message);
        }
      }));
    });
requestBepOption
Description

These are the available BEP request configuration options for receiving a private communication tunnel.

Type

object

Property
Type
Description
success
function
This is the success callback function.
error
function
This is the error callback function.
requestBepOption.success(result)
Type

function

Arguments
Argument
Type
Description
result
string
Parses the result of the BEP request to the callback function.
Example Code
app.get('/localDevices', (request, response) => {
    context.edge.requestBep({
        success: (result) => {
            console.log(result.data);
        }
    });
    // ...
});
requestBepOption.error(error)
Type

function

Arguments
Argument
Type
Description
error
string
Parses the error from the BEP request to the callback function.
Example Code
app.get('/bep', (request, response) => {
    context.edge.requestBep({
        error: (error) => {
            response.end('Cannot get BEP!');
        }
    });
    // ...
});

Your feedback is important to us ~