REST Lua Agent

Introduction

The RestLuaAgent is an asynchronous helper for Lua scripts running within the LogicApp. It is used for sending out REST client requests.

The RestLuaAgent communicates with one or more instances of the RestClientApp which can be used to communicate with one or more external REST servers.

The RestLuaAgent communicates with the RestClientApp using the REST-C-… messages.

Configuring RestLuaAgent

The RestLuaAgent is configured within a LogicApp.

    <?xml version="1.0" encoding="utf-8"?>
    <n2svcd>
      ...
      <applications>
        ...
        <application name="Logic" module="LogicApp">
          <include>
            <lib>../apps/logic/lib</lib>
          </include>
          <parameters>
            ...
            <parameter name="default_rest_app_name" value="REST-CLIENT"/>
          </parameters>
          <config>
            <services>
              ...
            </services>
            <agents>
              <agent module="RestClientApp::RestLuaAgent" libs="../apps/rest/lib"/>
            </agents>
          </config>
        </application>
        ...
      </application>
      ...
    </n2svcd>

Under normal installation, following agent attributes apply:

Parameter Name Type XML Type Description
module RestClientApp:: RestLuaAgent Attribute [Required] The module name containing the Lua Agent code.
libs ../apps/rest/lib Element Location of the module for RestLuaAgent.

In addition, the RestLuaAgent must be configured with the name of the RestClientApp with which it will communicate. This is configured within the parameters of the containing LogicApp.

Parameter Name Type XML Type Description
parameters Array Element Array of name = value Parameters for this Application instance.
.default_rest_app_name String Attribute Default name for the RestClientApp with which RestLuaAgent will communicate.
.rest_app_name_ String Attribute Use this format when RestLuaAgent will communicate with more than one RestClientApp.
(Default = RestLuaAgent uses only the default route/REST end-point).

Invoking RestLuaAgent

A Lua Script can access the RestLuaAgent rest action with code such as the following:

    local n2svcd = require "n2.n2svcd"
    local rest_client_api = require "n2.n2svcd.rest_client"

    local handler = function (soap_args)
        local response = rest_client_api.request (nil, {
            host = 'www.nsquared.nz',
            path = '/cgi-bin/search.cgi',
            query = { section = 'FAQ', subsection = 'site' }
        })
        if (response.code ~= 200) then
            error ("Failed to access search page.")
        end
        if (not response.content) then
            error ("Search page returned no content.")
        end

        return { NUM_BYTES = str.length (response.content) }
    end

    return n2svcd.handler (handler)

This is standard Lua-style library usage. The n2/n2svcd/rest_client.lua library is loaded with require "n2.n2svcd.rest_client". Then methods are invoked on the returned library object.

This example passes nil as the rest endpoint identifier. This routes the rest request to the default configured RestClientApp name. If more than one rest endpoint is present, then the first parameter is the “route”, or rest endpoint key.

The RestLuaAgent API

All methods may raise a Lua Error in the case of exception, including:

.request

The request method accepts an request object parameter with the following attributes.

Field Type Description
route String The identifier of the rest endpoint to access, or nil for the default.
request Object Container for the parameters of the REST request that we are to send.
.host String The hostname to which the REST HTTP(S) request should be sent.
(Default = Host as configured in the RestClientApp)
.port Integer The port number to which the REST HTTP(S) request should be sent.
(Default = Port number as configured in the RestClientApp, or 80 or 443)
.path String The URI path with which the request should be sent.
(Default = Path as configured in the RestClientApp)
.query String or Object The URI query string (the part following "?" in the URI) as per RFC 3986.
Specify either a simple String, or an Object which will be encoded for you.
(Default = None)
.fragment String The URI fragment string (the part following "#" in the URI).
(Default = None)
.method String The HTTP Request method.
(Default = POST if content is defined, otherwise GET)
.content_type String The HTTP Request Content-Type header value.
(Default = Content-Type as configured in the RestClientApp)
.content String The HTTP Request content.
(Default = None)
.username String Username for authentication (if security is enabled).
(Default = Username as configured in the RestClientApp)
.password String Password for authentication (if security is enabled).
(Default = Password as configured in the RestClientApp)
.security basic/none Security mechanism to use in the REST HTTP(S) request.
(Default = Security as configured in the RestClientApp)
.http_headers Array of Objects Additional user-level header objects to apply to an outbound HTTP Request (see below for object structure).
These headers are added after any headers defined by static RestClientApp application configuration.
You should not set the Content-Type or Content-Length headers.
(Default = No Additional Headers)

Each object in the request.http_headers Array has the following structure.

Field Type Description
.name String [Required] The name of the HTTP Request header.
.value String [Required] The full string value of the HTTP Request header.
.replace 0 / 1 If 1 then all previous headers of this name are removed, and this header replaces them.
(Default = Append to the existing headers, do not replace)

The request method returns an response object with the following attributes.

Parameter Type Description
response Object Container for response fields copied from the REST-C-RESPONSE message.
.code Integer The HTTP Response Status Code (e.g. 200)
.content_type String The HTTP Request Content-Type header value, if present.
.content String The HTTP Request content, if present.
.http_headers Array of Object The list of HTTP headers parsed from the HTTP Response (see below for object structure).
All HTTP headers are present, including Content-Length and Content-Type.
If a HTTP header was repeated in the HTTP Response, then it is repeated in this Array.

Each object in the response.http_headers Array has the following structure.

Field Type Description
.name String [Required] The name of the HTTP Response header.
.value String [Required] The full string value of the HTTP Response header.

[Fragment] Example REST client request:

    local response = rest_client_api.request (nil, {
        host = 'www.nsquared.nz',
        path = '/cgi-bin/search.cgi',
        query = 'FAQ',
        http_headers = {
            { name = 'Set-Cookie', value = 'FOO=Value+1' },
            { name = 'Set-Cookie', value = 'BAR=https%3A%2F%2Fwww.example.org%2F' }
        }
    })
    if (response.code ~= 200) then
        error ("Failed to access search page.")
    end
    if (not response.content) then
        error ("Search page returned no content.")
    end