Integration Gateway

The Integration gateway facility allows you to define custom endpoints that can support custom authentication methods, request validation, and rate limiting.

These endpoints can be used to define custom endpoint for incoming webhooks, to process data provided by some external integration, or to proxy requests to another service.

Most of the basic operations can be achieved with the built-in functionality; more advanced operations can be implemented with simple JavaScript code snippets or workflows.

Defining a new endpoint

To define a new endpoint, navigate to your Corteza instance (for example http://latest.cortezaproject.org/) and click on the "admin area" application.

app selector
Figure 1. The screenshot shows the app selector and the admin area application.

In the admin area, navigate to the System  Integration Gateway sub-page. From the admin area you can create and update your endpoints, as well as manage their access control.

route list
Figure 2. The screenshot shows the route list screen.

When you click on the new button, a new screen will appear where you need to provide the base parameters of your endpoint.

route create
Figure 3. The screenshot shows the user interface for creating a new endpoint.
  • endpoint defines the path for the endpoint,

  • method defines what HTTP method the endpoint will listen for.

The endpoint will be accessible under $BASE_URL/api/gateway$YOUR_ENDPOINT. To exemplify; the /test-api endpoint for the https://latest.cortezaproject.org instance is available under https://latest.cortezaproject.org/api/gateway/test-api

DevNote can I have multiple endpoints with same routes but different methods?

When you submit the forum, an additional "filter list" section opens below the base parameters. These filters allow you to validate and process requests; as well as defining the response.

Later sections go more in depth regarding specific filters, what they do, and how they should be used.

route filters
Figure 4. The screenshot shows the user interface for attaching filters to the endpoint.

Endpoint filters

Filters allow you to validate and process requests; as well as define the response.

Each endpoint can define at most one filter of the given type.

Prefilter

Prefilters allow you to validate the request to determine if the given endpoint should process it. With prefilters, you can implement custom authentication and validation methods.

It is currently not possible to use the built-in authentication facility to authenticate requests. This will be added in the future.

Table 1. The list of available prefilters:

Query parameters

The query parameters prefilter allows you to define a condition which asserts if the request can be processed by this endpoint based on the query parameters.

The query parameters are passed into the expression evaluation engine as they were provided. To examplify; the following query parameters ?param1=value1&param2=value2 would be referenced as param1 and param2 in the expression.

Refer to the expression reference for details regarding writing these expressions.

The following example checks if the given HTTP request defines the token query param of "super-secret-value".

Endpoint definition:
  • endpoint: /test-query

  • method: GET

  • query parameters prefilter expression: token == "super-secret-value"

An example of an HTTP request that conforms to the filter:
curl -X GET $BASE_URL/api/test-query?token=super-secret-value
An example of an HTTP request that does not conform to the filter:
curl -X GET $BASE_URL/api/test-query?token=some-other-value-i-guessed

Multi-word query parameters can currently not be used.

Multi-value query parameters can currently not be used.

Header

The header prefilter allows you to define a condition which asserts if the request can be processed by this endpoint based on the request’s headers.

All system defined headers are passed into the expression evaluation engine as provided. User-define headers will automatically be converted into the snake-case + PascalCase format. To examplify; test-header will become Test-Header and test becomes Test.

The following header test: value would be referenced as Test in the expression.

Refer to the expression reference for details regarding writing these expressions.

The following example checks if the given HTTP request defines the Token header of "super-secret-value".

Endpoint definition:
  • endpoint: /test-query

  • method: GET

  • header prefilter expression: Token == "super-secret-value"

An example of an HTTP request that conforms to the filter:
curl -X GET $BASE_URL/api/test-query \
  -H 'Token: super-secret-value'
An example of an HTTP request that does not conform to the filter:
curl -X GET $BASE_URL/api/test-query \
  -H 'Token: some-other-value-i-guessed'

Multi-word headers can currently not be used.

Multi-value headers can currently not be used.

Processing

A processor defines the core business logic that the endpoint performs. Corteza allows you to process arbitrary payloads, such as a structured JSON or a binary attachment.

Most of the basic operations can be achieved with the built-in functionality; more advanced operations can be implemented with simple JavaScript code snippets or workflows.

Table 2. A list of available processors:

Workflow processer

The workflow processor allows you to bind a workflow to the endpoint. Refer to the workflow processing for details regarding the interaction.

Payload processer

The payload processor allows you to handle the request’s payload with the help of JavaScript.

Refer to the JavaScript processing section for more details.

Postfilter

Postfilters allow you to finalize the request lifecycle depending on the result of the processing.

Table 3. A list of available postfilters:

Redirection

The redirect postfilter enriches the response payload with the required redirect HTTP headers.

Default JSON response

The JSON response postfilter enriches the response headers with the application/json content type and JSON encodes the processing results.

JavaScript request processing

The API GW processing filter includes support to process the request using arbitrary JavaScript code.

DevNote what restrictions does Goja implement?

The provided JavaScript code is automatically wrapped by a function with the signature of:

function (input: Scope): unknown {
  // {{snippet}}
}

To examplify; the code snippet of return "Hello, World!" would become:

function (input) {
  return "Hello, World!"
}

The following example code snippet takes in the provided name and surname of our users and returns an array of fullname parameters.

// We firstly need to get the body of the request
var b = JSON.parse(readRequestBody(input.Get('request').Body));

return {
  // Assure correct casing
  "results":
    b.map(function({ name, surname }) {
        return {
          "fullname": name[0].toUpperCase() + name.substring(1) + " " + surname[0].toUpperCase() + surname.substring(1)
        }
    }),
  "count": b.length
};

The following cURL example invokes the above JavaScript function.

curl -X GET $BASE_URL/api/test-js \
  -H "Content-Type: application/json" \
  -d "[{\"name\":\"johnny\", \"surname\":\"mnemonic\"},{\"name\":\"johnny\", \"surname\":\"knoxville\"}]";

Function arguments

The code snippet receives a single argument, input, that contains the entire request.

The argument has the signature of:
interface {
  Set: (k: string, v: unknown) => void;
  Get: (k: string) => unknown;
}
Table 4. The input object parameters:

request

The entire HTTP request object. Refer to the GO documentation for detils regarding the signature.

opts

Integration gateway configuration. Refer to the source for details.

DevNote generate above opt. docs

payload

The string encoded request body content. The content is extracted from request.Body

Function result

The result of the JavaScript snippet is provided to the post filters that prepare and return an HTTP response.

When the result is a string, such as Hello, World!, the result is used as is.

When the result is a non-string value, such as { key: "value" }, the result is JSON encoded.

Built-in function reference

Function Signature Description Example

readRequestBody

readRequestBody

readRequestBody(input: reader): string

The function returns the contents of the provided request object.

Debugging

System logs

Enable debug logging in your .env file. Refer to the DevOps guide for details.

Inspecting docker logs

By default, Corteza logs are accessible via Docker logs. To access these logs, you need to firstly navigate to the directory where your Corteza instance resides in.

An example of navigating to the Corteza instance directory:
cd /opt/deploy/{CORTEZA_INSTANCE}/

You can use the docker-compose logs server command to access the logs outputted by the server.

Refer to the docker-compose logs documentation for available flags. Using docker-compose logs -f --tail=20 server will follow the logs (new logs will be appended at the bottom) and limit the output to last 20 logs.

A truncated example of running the log command:
docker-compose logs -f --tail=20 server

server_1  | 12:53:14.862        DEBUG   rbac    rbac/service.go:102     allow delete for corteza::compose:record/245030892240891907/245030893465497603/246932114543603715       {"bypass": [], "context": [], "common": [245030892072923139], "authenticated": [245030891334791171], "anonymous": [], "identity": 250804535289769987, "indexed": 63, "rules": 420}

You can also use grep or log filtering to show only specific logs. Refer to the DevOps guide for details regarding logging.

An example of using grep to show only debug logs:
user@server:/opt/deploy/{CORTEZA_INSTANCE}/$ docker-compose logs -f --tail=20 server | grep DEBUG
server_1  | 13:52:29.636        DEBUG   rbac    rbac/service.go:102     allow triggers.manage for corteza::automation:workflow/248229091554160643
Last updated 2021-09-27 18:01:45 +0200
Some content has been disabled in this document