# API Construction
Quickly build out an API using the cloud.api
module by assiging functions to HTTP methods.
You trigger these processes and return the resulting data to the client in various formats.
These function/HTTP method combos are generally referred to as Routing Methods.
Starting an API
Your API will reside in the api.lua
file found in the project directory you want to work with.
Inside this file, you will want to start with the following structure, which follows the same structure of many Lua modules:
--apps/myapp/api.lua --=========================================================-- --== Get an instance of the Cloud API Object --=========================================================-- local api = cloud.api() -- Routing Methods will be added here. --=========================================================-- --== Return the API Object to the core --=========================================================-- return api
Routing Methods
Routing methods come in two formats, both based on the incoming HTTP method, specifically GET
and POST
.
POST
Methods
When using the Corona SDK client module, your requests are sent as POST
by default. You can build endpoints for your API calls like so:
--apps/myapp/api.lua local api = cloud.api() --=========================================================-- --== Create an "echo" routing method --=========================================================-- function api.post.echo( input ) return input end return api
Endpoint Schema
The code above generates an endpoint at https://your.coronium.instance/myapp/echo
By default this function will only run when the project key is passed in the X-Project-Key
header, and requested with an HTTP POST
method. This process happens automatically if you're using the Corona SDK module.
Returning Data
In the above function we don't return anything to the client, which is required to complete the client lifecycle.
The Circle of Life
You must always return
data from the Routing Methods.
Note: Without returning data to the client, you risk creating a "dangling" connection, which only uses resourses, for no purpose.
In the case of our "echo" function, it's very simple:
--apps/myapp/api.lua local api = cloud.api() function api.post.echo( input ) return input --echo data back to client end return api
GET
Methods
If you're using the Corona SDK module exclusivly, you won't need to set up any GET
methods. If you plan on having user-facing pages or functionality, then you will use the GET
methods.
Heads Up!
A 'GET' method is inheritly "public" unless set otherwise.
A GET
Routing Method is nearly identical to a POST
:
--apps/myapp/api.lua local api = cloud.api() function api.get.echo(input) return input --echo data back to client end return api
Can you spot the difference?
Incoming Data
A number of parameters are passed to a Routing Method when it's called. One of the more used, is the input
data.
Input data is always a Lua table and generated slightly different depending on the HTTP method request type.
For GET
requests, the input data is gathered from the query string as name=val
pairs and converted to a table.
A POST
requests data is built from the "body" posted. Coronium 2 expects JSON data in the POST
body, and will convert it into a Lua table upon entry to the Routing Method.
Method Parameters
A Routing Method has a number of passed in parameters that you can access for various use cases. The full signature of a Routing Method is as follows:
api.METHOD.ACTION(input, isAjax, headers, method)
Parameters
Name | Description | Type |
---|---|---|
input |
A table with any incoming data from the client. | table |
isAjax |
A flag to check whether request is Ajax. | boolean |
headers |
A table of the HTTP request headers. | table |
method |
The HTTP request method. | string |
Example
... function api.post.stats(input, isAjax) if isAjax then return cloud.error('no ajax!') end return input end ...
Returning Data II
Much like the incoming parameters, the return
has some additonal options as well.
The full signature for the data return
is as follows:
return output[, contentType[, headers]]
Parameters
Name | Description | Type |
---|---|---|
output |
A string, number, boolean, or table to send to the client. | mixed |
contentType |
A content type constant, default: cloud.JSON |
constant |
headers |
A table of the HTTP request headers. | table |
Example
... function api.get.story() --just some plain text local t = "Once upon a time" return t, cloud.TEXT end ...
The output above will be render as plain text, with no decorations or JSON encoding.
cloud.JSON
The cloud.JSON
content type is the default output, so is not required to be specified. With this content type, any data return
-ed will attempt to be converted to JSON before being sent down the wire.
For end clients like the Corona SDK module, this data is converted to a Lua table for client consumption.
The result
key
All JSON data is returned in an enclosing object with a result
key. This result
may hold a string, number, boolean, or object.
When processed by the Corona SDK module, this data is converted to a Lua table. You can access this data with the regular Corona event.response
from the network event returned.
String Example
In the Cloud...
--apps/users/api.lua ... function api.post.getUserName() return "Mr. Jones" --a string end ...
This will send {"result":"Mr. Jones"}
down the wire.
In Corona SDK...
local function listener(event) if event.phase == "ended" then print(event.response.result) -- "Mr. Jones" end end local req = cloud:request('/users/getUserName', {}, listener)
This would be the same results expected when passed a single number, or boolean value.
Table Example
When passing a table object, the data will be JSON encoded before being sent down the wire. As above, the data will reside in the event.response
key in Corona SDK.
In the Cloud...
--apps/store/api.lua ... function api.post.product() local product = { sku = 001, desc = "widget", inStock = false } return product end ...
In Corona SDK...
local function listener(event) if event.phase == "ended" then print(event.response.inStock) -- false end end local req = cloud:request('/store/product', {}, listener)
cloud.HTML
You can generate and display dynamic and static web pages using data from your Coronium 2 instance. The content is not wrapped by any result
object.
Content Generation
See the cloud.template
module and Generating Pages for more information.
cloud.TEXT
If you'd like just plain text with no decorations or wrappers, then use this content type.
... function api.get.stats() local cpu = '100%' return cpu, cloud.TEXT end ...