This article demonstrates a set up that is probably mainly of theoretical interest or maybe useful in demonstrations. I describe how we can invoke an OCI serverless Function through the API Gateway and ask the serverless function for values that are read from a [read only] cache. This cache is implemented by an API Gateway deployment of [backend] type Stock Response (see this article for an introduction on API Gateway and the API Deployment of type Stock Response).
The code in this article shows a number of potentially useful things:
- how to make the implementation of the serverless function easily testable – by using Fn’s func.js as a wrapper to an impl.js module that can also be invoked stand alone from the command line
- how to pass configuration values to a Function – readable inside the function as Environment Variables
- how to make an asynchronous call from the Node implementation of the function to the API Gateway, using NPM module request-promise and how to get the headers from the response in addition to the body
- specifically, the asynchronous call from the Function is to API Gateway (and possibly from API Gateway to other Functions, although in this case a Stock Response route is invoked)
- how to use API Gateway to create multiple read only caches using the backend type Stock Response for API deployments
The code can be found in this GitHub Repo: https://github.com/lucasjellema/oci-cloud-native-explorations/tree/master/cache-controller.
The starting point I am assuming in the article is:
- An API Gateway is up and running on OCI (see this article for an introduction) – and it has been granted permissions to invoke functions
- An Fn development environment for Oracle Functions is available, configured for deployment to OCI (see this article for the first steps)
The steps in this article:
- Create Route with backend type Stock Response on API Gateway – and have it return the cache contents
- Create a function (runtime Node) in the local Fn environment
- Implement a Node module that invokes a REST API (the API Gateway route that returns the stock response with the cache); test this module as stand alone Node application
- Connect func.js (created by Fn as the function’s request handler to the developed Node module
- Configure the Cache API’s endpoint as configuration variable on the Fn function
- Deploy the Fn function to OCI
- Create a Route on API Gateway backed by the new Function
- Invoke the Cache route on API Gateway to retrieve some values from the cache
1. Create Route with backend type Stock Response on API Gateway – and have it return the cache contents
In the existing API Gateway, create an APi Deployment with path prefix /fn and a new route with path /cache/physics.
Set the Body of the Stock Response to – a cache of some of nature’s constants:
{“c”: {“name”:”speed of light in a vacuum”, “value”:”299792458″, “unit”:”m/s”}
,”G”: {“name”:”gravitational constant”, “value”:”6.67430E−11″, “unit”:”N m2/kg2″}
,”h”:{“name”:”planck constant”,”value”:”4.135667696E−34″,”unit”:”Js”}
,”e”:{“name”:”elementary charge”,”value”:”1.602176634E−19″,”unit”:”C”}
,”NA”:{“name”:”avogadro constant”,”value”:”6.02214076E23″,”unit”:”1/mol”}
}
Make a test call to see if the function is accessible and returns the expected response.
2.Create a function (runtime Node) in the local Fn environment
Using the Fn CLI:
fn init –runtime node cache-controller
3. Implement a Node module that invokes a REST API (the API Gateway route that returns the stock response with the cache); test this module as stand alone Node application
It is perfectly possible to develop the logic of the function without thinking at all about Fn and the serverless framework on OCI. We can just develop a Node application that does whatever we need it to do. We can run this application from the command line while testing it. The application needs an entrypoint – in this case a function that is exported and that takes parameters for all values it needs from the HTTP request that will trigger execution of the function.
In this case, function getFromCache is that entrypoint. It takes the key [of the object to be returned from cache] and the name of the cache. The function is exported from the module and could be imported into and invoked from func.js – the Fn request handler for the Node runtime.
This module leverages NPM module request-promise for making an asynchronous HTTP call to the Cache API on API Gateway. Note the transform function that is passed – this is needed to retrieve headers from the response in addition to just the body. Read this entry on StackOverflow for details.
In order to get access to the NPM module request-promise, it needs to be installed:
npm i request-promise –save
npm install
The Node module is invoked from the command line with two command line arguments – the first is the cache key and the second the name of cache. For example:
node cacheController NA physics
4. Connect func.js (created by Fn as the function’s request handler to the developed Node module
Func.js is initially generated by Fn, leveraging the Node FDK to handle the HTTP request that triggers the function. I have extended the generated func.js in several ways:
- import module cacheController
- derive the name of the cache from the input object
- derive the cache key from the input object
- make an asynchronous call to function getFromCache in the cacheController module
- construct the response object from the response from this function
5. Configure the Cache API’s endpoint as configuration variable on the Fn function
Make this call through the Fn command line tool:
fn config function lab-app cache-controller stock_api_endpoint https://f6.apigateway.us-ashburn-1.oci.customer-oci.com/fn/cache/
or set the configuration value through the Functions console on OCI:
6. Deploy the Fn function to OCI
On the command line using the Fn CLI:
fn deploy –app lab-app
7. Create a Route on API Gateway backed by the new Function
In the OCI Console for API Gateway, create a Route for path /cache-controller, associated with back end of type Oracle Function and specifically with function cache-controller in app lab-app:
8. Invoke the Cache route on API Gateway to retrieve some values from the cache
From the command line with Curl or from Postman or any other HTTP client – call the Function endpoint: <API Gateway Endpoint>/fn/cache-controller and pass a JSON object in the body that contains properties key and cache for the cache key and the name of the cache:
curl -X GET \
https://ohv2poh4mm.apigateway.us-ashburn-1.oci.customer-oci.com/fn/cache-controller \
-d ‘{“key”:”NA”, “cache”:”physics”}’
Resources
The code can be found in this GitHub Repo: https://github.com/lucasjellema/oci-cloud-native-explorations/tree/master/cache-controller.
Get headers from response to asynchronous HTTP call with NPM module request-promise: read this entry on StackOverflow for details.
Get an API Gateway up and running on OCI: see this article for an introduction
Prepare an Fn development environment for Oracle Functions – configured for deployment to OCI: see this article for the first steps
Project Fn – Quickstart – https://github.com/fnproject/fn#quickstart
Project Fn – Configuration Variables – https://github.com/fnproject/docs/blob/master/fn/develop/configs.md and https://github.com/fnproject/docs/tree/master/fdks/fdk-java/examples/configuration-variables
NPM Module request-promise – https://www.npmjs.com/package/request-promise
Encode String in URI format: https://stackoverflow.com/questions/6554039/how-do-i-url-encode-something-in-node-js with encodeURIComponent; also see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent