Advanced Endpoints
Advanced Endpoints is a very powerful way to embed your corporate logic directly in the Web API. This eliminates the need of the middleware between inmation and ERP or other business applications. For instance, Web API can directly react on ERP HTTP requests and respond in a format, which is most suitable for the caller.
-
Allows advanced endpoint implementation.
-
Behave as a native endpoints.
-
Is able to route any URL.
-
Supports many HTTP methods.
-
Accepts various types of arguments
-
Response can be 'any' text based format
Description
The advanced endpoint embeds custom endpoints by hosting Lua libraries in the system. The name of the Lua library will be the first part of the custom path, the second part of the custom path will be the function name, unless the library returns a function itself. For example: api/v2/execfunction/corporate/readMachineHistory. In this example is corporate the name of the Lua library and readMachineHistory is a name of the function, which will be executed to process the request.
The implementation of the Advanced Endpoint is done in Lua. The Lua script will be stored as a library. Such a library can be implemented in two distinctive ways:
-
Returning an object (Lua table) containing function(s).
-
Returning one function.
The signature of the function is always the same. Containing three arguments: (arg, req, hlp).
-
(
arg
) argument
This argument contains the body of the HTTP request and will always be passed as a dictionary (Lua table). In case the request body is not set or empty, the arg
argument will be an empty table. In all other cases the data
field of the arg
Lua table contains the value of the HTTP body. The 'data' field will be a Lua table in case the request body is a JSON array.
-
(
req
) argument
A Lua table which contains the information about the request. On root level the req
argument contains the following fields:
-
access_token_payload
Optional, holds the payload of the provided JSON Web Token (JWT). -
headers
A Lua table containing the HTTP request headers. -
method
The HTTP method of the request, like DELETE, GET, POST, PUT. -
path
The part of the path after the function name. In case no path is provided the value will be an empty string. -
query
A Lua table which contains the provided URL query parameters. In case no query parameter is provided the value will be an empty Lua table. -
remote_ip_address
The client’s IP Address. -
server_oid
The object id of the Web API Server object, which processes the request. -
context_info
A Lua table which contains the context information of the request. Thectx
field specifies the path of the object in which the script is running. Theprofile
field contains the name of the profile used as security context. Thetopic
field contains the name of the endpoint, likeexecfunction
,read
,write
. In case of an Advanced Endpoint or Exec Function request theexecfunction
field holds a Lua table containing the fieldslib
andfunc
. -
url
A Lua table which contains the full URL (href
) and its componentsprotocol
,hostname
,port
,pathname
and optional thesearch
andhash
.
The advanced endpoint accepts any path. The part of the path after the function name can be accessed by the path
field of the request req
argument. URL query parameters can be accessed by the query
fields. The path
and query
fields can be used to handle routing withing Lua.
/api/v2/execfunction/corporate/readMachineData/lab/1234
This will result in the readMachineData
will be executed of the library corporate
where the /lab/1234
can be accessed on the req.path
parameter.
The provided query parameters in the URL are accessible through the query
field of the request req
argument. This field is a Lua table which contains the query parameter names as keys and query parameter values as strings. In case a query parameter is provided more than once this query table contains one entry of which the value is a Lua table string array.
The HTTP request type can be accessed by the method
field. This field contains one of the following string values: DELETE
, GET
, HEAD
, OPTIONS
, PUT
, POST
, PATCH
.
-
(
hlp
) argument
The hlp
argument is helper object which contains convenience functions, like checkpermission
and createResponse
.
The createResponse
function can be used to set the response body, error, HTTP status code and response headers, which should be returned by the Web API.
Extended explanation and examples of how to use the helper function can be found in the execfunction endpoint documentation
.
Examples
The Advanced Endpoint can make use of the standard logic in order to e.g. read historical data. This way it is very easy to add custom logic in combination with standard API functionality. The standard API logic can be accessed via the inmation.api
library.
Example - Read Historical Data
This simplified example reads historical data for one of the performance counters in which a caller only need to supply a start time.
local inAPI = require('inmation.api')
local lib = {}
function lib:readperfcounters(arg, req, hlp)
arg = arg or {}
local now = syslib.currenttime()
local startTime
if type(arg.starttime) == 'string' then
-- Use starttime supplied by the caller.
startTime = arg.starttime
else
-- Fallback to a default relative starttime
startTime = syslib.gettime(now-(5*60*1000))
end
local endTime = syslib.gettime(now)
local qry = {
start_time = startTime,
end_time = endTime,
intervals_no = 100,
items = {
{
p = "/System/Core/Performance Counter/Core/Core/CPU",
aggregate = "AGG_TYPE_INTERPOLATIVE"
}
}
}
return inAPI:readhistoricaldata(qry, req, hlp)
end
return lib
Invoke this endpoint by:
Method: POST
URL: /api/v2/execfunction/my-lib/readperfcounters
Body:
{
"start_time": "2019-04-02T10:00:00.000Z"
}
Example - Read Raw Historical Data with filter
This example shows how to read raw historical data for one of the performance counters. Start time and a value, which acts as a filter, are the parameters, which need to be supplied by the caller. The filter will only return values, which are greater than or equal to the provided value.
local inAPI = require('inmation.api')
local lib = {}
function lib:readperfcounters(arg, req, hlp)
arg = arg or {}
local now = syslib.currenttime()
local startTime
if type(arg.starttime) == 'string' then
-- Use starttime supplied by the caller.
startTime = arg.starttime
else
-- Fallback to a default relative starttime
startTime = syslib.gettime(now-(5*60*1000))
end
local endTime = syslib.gettime(now)
local qry = {
start_time = startTime,
end_time = endTime,
filter = {
v = {
["$gte"] = arg.limit or 50
}
},
items = {
{
p = "/System/Core/Performance Counter/Core/Core/CPU",
}
}
}
return inAPI:readrawhistoricaldata(qry, req, hlp)
end
return lib
Invoke this endpoint by:
Method: POST
URL: /api/v2/execfunction/my-lib/readperfcounters
Body:
{
"start_time": "2019-04-02T10:00:00.000Z",
"limit": 35
}
Example - Read Raw Historical Data and respond in CSV format
This example shows how to read raw historical data for one of the performance counters. Start time and a value, which acts as a filter,are the parameters, which need to be supplied by the caller. The filter will only return values which are greater than or equal to the provided value. The createResponse
helper function is used to set the Content-Type
of the response body to CSV format.
local inAPI = require('inmation.api')
local lib = {}
function lib:readperfcounters(arg, req, hlp)
arg = arg or {}
local now = syslib.currenttime()
local startTime
if type(arg.starttime) == 'string' then
-- Use starttime supplied by the caller.
startTime = arg.starttime
else
-- Fallback to a default relative starttime
startTime = syslib.gettime(now-(5*60*1000))
end
local endTime = syslib.gettime(now)
local qry = {
start_time = startTime,
end_time = endTime,
filter = {
v = {
["$gte"] = arg.limit or 50
}
},
items = {
{
p = "/System/Core/Performance Counter/Core/Core/CPU",
}
}
}
local respData = {}
local res = inAPI:readrawhistoricaldata(qry, req, hlp)
local rawData = res.data or {}
local histData = rawData.historical_data or {}
local queryData = histData.query_data or {}
if #queryData > 0 then
queryData = queryData[1]
local items = queryData.items or {}
if #items > 0 then
items = items[1]
for i,t in ipairs(items.t) do
local value = items.v[i]
local timestampISO = syslib.gettime(t)
local row = ("%s,%s"):format(timestampISO, value)
table.insert(respData, row)
end
end
end
local result = table.concat(respData, '\n')
return hlp:createResponse(result, nil, 200, { ["Content-Type"] = "text/csv" })
end
return lib
Invoke this endpoint by:
Method: POST
URL: /api/v2/execfunction/my-lib/readperfcounters
Body:
{
"start_time": "2019-04-02T10:00:00.000Z",
"limit": 35
}