Skip to content

API

The API module allows you to create server-side api methods that can be called using the client-side API module.

A server-side api is useful for more complex application logic, and in fact, is the only way to access the full functionality of the MySQL and Mongo modules. Some modules are only available server-side.

Projects

Server-side api methods are housed in "API Projects" that are stored on the server. Projects allow you to create specific functionality for an API, which can then be shared amongst multiple client applications.

Managing Projects

You manage projects by using the Coronium Webmin API Builder.

Add Project

Log into your browser based Webmin and go to the API Builder section. Click the New Project button and follow the instructions.

After creating your project, you can use the API Builder code editor to build your custom API code.

Delete Project

Log into your browser based Webmin and go to the API Builder section. Click the Delete button for the project you want to delete, and follow the instructions.

Project Files

main.lua

Webmin Code Editor

You can edit the main.lua and other project files using a visual code editor. Go to the API Builder section in the Webmin and click the project file you would like to edit.

The main.lua file will contain your custom server-side api methods for the project. By default a simple "echo" test method is generated.

main.lua example

-- Coronium Core API
local api = core.api()

function api.test( input )
  return input
end

return api

You can call this method from the client using the client-side API module.

Client-side example

core.init({
  server = "https://your.coronium.host",
  key = "<coronium-server-key>",
  scope = "<application-scope>",
  api = "default"
})

local apiResponse(evt)
  if evt.error then
    print(evt.error)
  else
    print(evt.result.name) -- Jimmy
  end
end
core.api.test({name="Jimmy"}, apiResponse)

Adding Files

There may be times when you would like to split up your API project code into seperate files. You can add new files to a project using the Webmin.

Go to the API Builder section of the Webmin and click the Add File button for the project you would like to add a file to and requiring it into the projects main.lua file.

The important thing to know about external file modules is that they cannot return output to the client directly. Only the main.lua file can send output back down to the client.

Because of this it is important that you set up your external file modules properly to return results back to the main.lua file for sending results downstream.

Example File Module

--project/default/db.lua
local db = {}

function db.getSomeData(params)

  local res, err = core.mysql.selectOne("products", {
    tbl = "toys",
    where = { color = params.color }
  })

  --we must return the result back to the main.lua
  return res, err

end

return 

Example Main Lua File

--project/default/main.lua
local db = require("project.db")

local api = core.api()

function api.doSomething(input)

  local res, err = db.getSomeData({color = "Red"})

  --here we can return data to the downstream client
  if not res then
    return core.error(err)
  end

  return res
end

return api

core.api

To create your api, you need to extend the core.api object. As shown in the main.lua file above, this is done like so:

local api = core.api()

Add your api methods to the api object, and finally return the api object at the end of the file.

Example

local api = core.api()

function api.addUser(input)
  ... --code here
end

return api

Input

Custom API methods are passed two parameters, which are a table of input values sent up from the client-side core.api method, and the scope of the current client call (see Application Scope).

Some methods may not send input, in which case the input parameter will be nil. Most often you will only use the input parameter.

Note

The input parameter is supplied from the client-side call (see client-side API). The scope is determined internally. You do not send the scope value in the client-side API call.

Example

local api = core.api()

-- Input only
function api.addUser(input)
  local name = input.name
  local age = input.age

  ...
end

-- Input and Scope
function api.getUser(input, scope)
  local res, err = core.users.getWithQuery(scope, {
    username = input.name
  })

  ...
end

return api

Return

All api methods must return a response. This can either be the result of the api operation, or an error (see errors below). You can only return a single response value.

A response value can be one of the following Lua types: String, Number, Boolean, or Table. String and Table values must be JSON encodable. The value returned will be sent back down to the client for consumption.

Example

local api = core.api()

function api.doSomething(input)

  return "Welcome to Coronium"
  --OR
  return 42
  --OR
  return true
  --OR
  return {name = "Sally", age = 34}

end

return api

To learn how to consume the response on the client, see the client-side API module.

core.error

Return an error response object to the client.

core.error(message, code)

Errors

At times you may want to indicate to the client that an error has taken place in the server-side api operation. To do this, you return a core.error response object. This will be interpeted by the client as an error event.

The core.error object requires a string message parameter, and an optional number based error code.

Example

local api = core.api()

function api.echoName(input)
  if not input.name then
    -- Return error with string only:
    return core.error("The name parameter is missing!")

    -- OR

    -- Return error with a custom status code too:
    return core.error("The name parameter is missing!", 110)
  end

  return "Hello, " .. input.name
end

return api

Some of the built in modules return an error string and an error code which you can pass downstream to the client. See each modules documentation for more information.

Example

local api = core.api()

function api.getUser(input)

  local user, err, code = core.users.get("aad3eba3-9c9c-9a1b-f236de1e3752")

  if not user then
    return core.error(err, code)
  end

  return user
end

return api

When using custom error codes, make sure to check the latest reserved Status Codes and choose something not listed there. Custom status codes should generally be in the 100-199 range.

Using Modules

Most often you will want to do something more useful than echoing data. You can use the server-side modules to add functionality to your api.

Examples

List the available collections in a Mongo database:

Server-side

--main.lua
local api = core.api()

function api.getCollections(input)

  --get the database name from the input
  local db_name = input.db_name

  --get a mongo db instance
  local db, err = core.mongo(db_name)

  --check for errors
  if not db then
    return core.error(err)
  end

  --get the collection list
  local list, err = db:listCollections()

  --check for errors
  if not list then
    return core.error(err)
  end

  --otherwise return the list
  return list

end

return api

Some things to note in the code above:

  • Errors from the server-side modules can be passed to the client with core.error.
  • Any return values from server-side modules can be used in the return.

To issue a call to this api method on the client, we use the client-side API module:

Client-side

local function apiResponse(evt)
  if evt.error then
    print(evt.error)
  else
    --got collection list
    for i=1, #evt.result do
      print(evt.result[i]) -- collection name
    end
  end
end

core.api.getCollections({db_name="app"}, apiResponse)

Get a user using a MySQL query:

Server-side

--main.lua
local api = core.api()

function api.queryUser(input)

  --get id number from the input
  local id = input.id

  --check for id value
  if not id then
    return core.error("Id is missing!")
  end

  --build sql query
  local q = core.sf("SELECT * FROM users WHERE id=%d;", input.id)

  --run the query
  local record, err = core.mysql.query("app", q)

  --check for error
  if not record then
    return core.error(err)
  end

  --return the record
  return record
end

return api

Client-side

local function apiResponse(evt)
  if evt.error then
    print(evt.error)
  else
    --result is a record
    print(evt.result.name) --output 'name' column
  end
end

core.api.queryUser({id=20}, apiResponse)

Client-Side MySQL

The following example can also be done directly from the client-side MySQL module.

Assuming we have a MySQL database properly created called "app", we can quickly insert a new record to the "users" table like so:

Server-side

--main.lua
local api = core.api()

function api.addUser(input)

  --insert data using EZ query method
  local id, err = core.mysql.insert("app", {
    tbl = "users",
    --pass the input directly, escaping string values
    values = core.mysql.escapeAll(input)
  })

  --check for error
  if not id then
    return core.error(err)
  end

  --return new record id
  return id

end

return api

Client-side

local function apiResponse(evt)
  if evt.error then
    print(evt.error)
  else
    print(evt.result) --result is id
  end
end

local data = {
  name = "Johnson",
  age = 32,
  active = true
}

core.api.addUser(data, apiResponse)