API Functions
Available since v1.4.0
API Functions enable you to create custom API endpoints using traditional Functions.
An API Function is a type of Function that can be triggered by a HTTP request. Instead of a Task for a traditional Function, an API Function will receive the HTTP request object as its input. The API Function can create an output object which resolves to a HTTP response.
Creating an API Function
In this example you will learn how to create, deploy and execute an API Function.
Create
The following code snippet illustrates a basic API function that returns the HTTP method used for the request in the response.
Deploy
Similar to traditional Functions, API Functions can be deployed by referring to the documentation provided in the Extra Horizon CLI: hello world (JS) example.
Execute
API functions can be executed by making requests to the /tasks/v1/api/<function_name>
endpoint. This endpoint can be targeted using the common HTTP methods. The URL can be extended by appending additional path parameters and a query string.
The SDK can be used to execute the API Function using the following example:
Please refer to the SDK documentation for further information on setting up the SDK.
Working with requests
The API Function receives the HTTP request as its input. The request is transformed to the standardized AWS API Gateway request format (version 2.0). By using this standardized format, we ensure that the API Functions can handle HTTP requests consistently across different programming languages.
Depending on your cluster configuration, Extra Horizon will handle Cross-Origin Resource Sharing (CORS) for you. Therefore, some OPTIONS
requests might not reach your API Function and additional headers could be added to the response you've generated.
Example API Function input
Here is an example of a request object received by an API Function as its input:
Request object properties
requestContext.http.method
The requestContext.http.method
field represents the HTTP method used to target the API function. Currently this can be any of the following values: GET
, POST
, PUT
, PATCH
, DELETE
, HEAD
and OPTIONS
.
rawPath
The rawPath
field refers to the path portion of the URL that comes after the Function name.
For the following URL:
The rawPath
value would be /hello/world
rawQueryString
The rawQueryString
field represents the unprocessed query string of the incoming HTTP request including the starting question mark.
For the following URL:
The rawQueryString
value will be ?param1=value
headers
The headers
field represents the headers of the incoming HTTP request. It is structured as an object, where each key-value pair corresponds to a header name and its value.
The header names within the headers
field are transformed to be all lower case, to ensure consistent and case-insensitive handling of headers.
Following headers are added by Extra Horizon when invoking the API Function:
x-exh-requesting-user-id
contains the id of the user making the request.x-exh-requesting-application-id
contains the application id of the oAuth application
These x-exh-requesting-
headers are guarded by the platform and can be trusted to be correct.
The following HTTP request will create the resultant header object:
isBase64Encoded
The isBase64Encoded
property indicates if the body
property of the request object has been Base64-encoded.
body
The body
field represents the body of the incoming HTTP request as string. It can be Base64-encoded based on the isBase64Encoded
property.
Always check the isBase64Encoded
property to know if the body
string needs to be Base64 decoded before usage.
No assumptions can be made for when the body is going to be Base64 encoded or not as it will vary.
Working with responses
An API Function is expected to generate an output object which will be resolved to the HTTP response. The output is defined by the standardized AWS API Gateway request format (version 2.0). By using this standardized format, we ensure that the API Functions can handle HTTP responses consistently across different programming languages.
Example API Function output
Here is an example response object of an API Function:
Response object properties
statusCode
The statusCode
field resolves to the status code in the HTTP response. The value can be between the 200
- 499
range. If a status code outside of that range is passed, an INVALID_API_FUNCTION_RESULT
error will be returned.
headers
The headers
field resolves to the headers in the HTTP response. It is structured as an object, where each key-value pair corresponds to a header name and its value.
If no Content-Type
header is present in the output, application/json
will be set as the default value. It is recommend to always explicitly set a Content-Type
header in the response object.
Also for the Content-Type
header, charset
could automatically be added to the header value in some cases. For example text/plain
could resolve to text/plain; charset=utf-8
.
The Connection
and Content-Length
header values are ignored as they're automatically added to the response.
body
The body
field resolves to the body in the HTTP response.
In order to include binary data within a body, such as images or audio files, it is necessary to convert it into a Base64 string and assign it to the body
field of the response object. Additionally, the isBase64Encoded
field must be set to true
.
If the response body does not contain binary data, you can directly include the data in its original format.
If the isBase64Encoded
field is set to true
, any other value then a Base64 string in thebody
field will result in an INVALID_FUNCTION_RESULT
error.
isBase64Encoded
The isBase64Encoded
field must be set to true
if the body
field of the response object is a Base64 encoded string representing the raw response body.
Permissions
To enable users to execute the function, appropriate permissions can be granted.
The executionOptions.permissionMode
property of the Function determines the execution restrictions based on its assigned value.
Permission Modes
One of the following values may be assigned to the permissionMode
property to enforce their respective execution restrictions.
permissionRequired
A user requires a permission as stated in the user permissions section. This is the default permission mode.
allUsers
A user must be logged in, but no permission is required.
public
Any party may execute this function without any restrictions.
User Permissions
Permissions for executing an API function can be assigned two levels of granularity.
The EXECUTE_API_FUNCTION
permission allows a user to execute all API functions.
The EXECUTE_API_FUNCTION:<function_name>
permission allows a user to execute the API function specified by the <function_name>
.
For further information regarding the application of permissions to users please refer to global roles.
Errors
An API function allows for direct control over the HTTP response. However standard errors may still occur. For instance the INVALID_FUNCTION_RESULT
error mentioned before.
It is possible to receive errors related to problematic code, such as invalid syntax or unhandled exceptions within the API Function. These present themselves as a LAMBDA_RUNTIME_EXCEPTION
including the original error.
For a complete list of errors please refer to the swagger documentation.
Further Examples
Working with the request body
As explained in the section about the request object, the body could be base64 encoded to support the reception of various content types. Consequently, to consume a received request within the function, it is necessary to pre-process the request body.
Complex requests, responses and routing
API functions offer a wide range of possibilities, including the ability to create full web services. The request is transformed to the standardized AWS API Gateway request format (version 2.0). By using this standardized format, allows the usage off existing 3th party packages to seamlessly integrate complex logic.
For instance when using the Node.js runtime, request routing can be implemented using a package like serverless-http and a popular web framework. Below is an example of an express simple web service as an API Function.
Please note that we are not affiliated with any of the specific packages mentioned above.
Creating an API Function with the CLI
The full folder structure of an API Function in TypeScript can be easily created with the Extra Horizon CLI:
Please refer to the CLI documentation for further information on setting up the CLI.
Monitoring
Available since v1.5.0
Every request made to an API Function is logged as an API Request, similar to how normal Function executions are saved as Tasks. These API Requests provide valuable information about the executed requests. The logs that an API Function generates during its execution are saved as API Request Logs.
API Requests
API Requests are a summary of the requests made to API Functions. They can be helpful to monitor and debug API Function calls.
The SDK can be used list API Requests using the following example:
Example of an API Request
API Request Properties
functionName
The functionName
refers to the name of the API Function that was invoked in the request.
method
The method
field represents the HTTP method used to target the API function.
path
The path
field refers to the portion of the URL that comes after the Function name. The query string will be included in the path.
For the following URL:
The path
value would be hello/world?param1=value
userId
The userId
field refers to the id of the Extra Horizon user that has performed the request.
applicationId
The applicationId
field refers to the id of the Extra Horizon oAuth application that has performed the request.
statusCode
The statusCode
field refers to the status code of the API Function's response or of a thrown error during its lifecycle
timestamp
The timestamp
field refers to the time the API Function was executed.
duration
The duration
field is the duration of the API Function execution in seconds.
error
When an error occurs during an API Function Request the error object is logged.
error.type
The error type defines where the error occurred during the API Function lifecycle and can have one of the following values:
invocation
: errors that occur before invoking the API Functionruntime
: errors that occurred during the execution of the API Functionresponse
: errors that occur during the response validation after the API Function has been executed
error.name
The name of the caught error
error.message
The message of the caught error
API Request Logs
API Functions may include logging statements during execution. These logs are saved as API Request Logs.
The SDK can be used list API Request Logs using the following example:
Example of an API Request Log
API Request Log Properties
timestamp
The timestamp
field refers to the time the log was printed.
message
The message
property contains the message being printed.
Limitations
Request and response size
The request and response sizes are both limited to 6 Megabytes
, after conversion to the standardized formats.
Function configuration
Unlike normal Functions API functions are limited to a timeLimit
of 30 seconds.
HTTP Methods
Currently the API Functions only support the GET
, POST
, PUT
, DELETE
, PATCH
, OPTIONS
and HEAD
HTTP methods.
Using an HTTP method that is not listed will result in an ENDPOINT_EXCEPTION
Status Codes
Currently the API Functions only support the status codes between 200 and 499.
RQL on the API Requests Logs endpoint
The RQL that can be used on the API Requests Logs endpoint is limited to only the ge
operator in combination with the timestamp
field.
Missing API Requests
We prioritize providing the API Function result over saving the API Request. In the rare case that saving an API Request fails, no error message will be provided and the API Request record will be missing.
Last updated