Developing serverless backends with OpenWhisk and API Gateway integrations

Andreas Nauerz
Apache OpenWhisk
Published in
7 min readMay 6, 2017

Part 1: IBM API Gateway

As actions can be seen as flexible and independently deployable microservices they are perfectly suited to build up entirely serverless microservice backends that expose functions via APIs.

In this context, APIs form the digital glue that links services, applications, sensors, and mobile devices to create compelling customer experiences and helps businesses to tap into new market opportunities. They allow you to bring new digital services to market, open revenue channels and exceed customer expectations.

With IBM’s API Gateway (available as open-source as well: https://github.com/openwhisk/openwhisk-apigateway) and Mashape’s Kong plug-in two API Gateway solutions to expose OpenWhisk actions via well defined APIs are meanwhile available — in this part of this article series we will focus on IBM’s API Gateway integration; in the second part that will follow soon we will focus on the Kong plug-in.

IBM’s API Gateway (meanwhile GA and thus ready for in-production usage), which is, in combination with IBM Bluemix OpenWhisk available for free, enables you to easily expose your OpenWhisk actions as APIs. It allows you to map API endpoints to OpenWhisk actions to expose these as serverless & easily addressable microservices.

General usage flow

In general, two different ways to map endpoints to actions are being supported:

  • Mapping API endpoint/verb combinations to specific actions individually Using a Swagger configuration file to map API endpoints to actions.
  • Mappings can be defined using the OpenWhisk CLI or UI.

First, developers implement the application logic they want to expose as OpenWhisk actions. Second, they define endpoints to be mapped to said actions to make them easily addressable:

Mapping API endpoints to OpenWhisk actions

IBM’s API Gateway provides the following functionality:

  • Security
    To stop unwanted usage of the data you supply, you can ensure that only users with the correct authentication can access your APIs.
    Methods being supported include API key, API secret, and OAuth validation.
    Supported OAuth providers include Google, Facebook, and GitHub.
  • Rate limiting
    You can enforce a rate limit to manage the number of calls that applications can make to your APIs. To do so you can specify a rate limit so that only a permitted number of calls can be issued per second, minute, hour, so that for instance, your backend is not overloaded. You can control this either by overall API or by each API key.
  • Analytics
    If you want to monetize the use of your APIs, you can use the analytics feature to track call usage. You can also monitor usage to understand how your APIs are being used so you can make informed decisions about how to update your APIs to increase adoption.

    You can view the following statistics about your APIs:
    - The number of responses and average response time in the last hour, or your specified time interval.
    - The number of API calls per minute.
    - The last 100 responses.
  • Sharing
    You can easily share your APIs with other developers inside or even outside your Bluemix organization.
  • Testing
    You can easily review and test your APIs via the integrated API Explorer.
  • Upload Swagger/OpenAPI Doc
    You can easily specify API management settings or import a YAML or JSON format OpenAPI 2.0 definition file that includes the settings.

Mapping API endpoints to OpenWhisk actions using the OpenWhisk CLI

Let’s examine how a specific action can be associated with an API endpoint using the OpenWhisk CLI (download from here: https://console.ng.bluemix.net/openwhisk/). You need to specify an API path, a verb (get, post, put, delete), and the action itself.

Note that you may have to issue the following command and select the proper namespace before being able to proceed:

$ wsk bluemix login --user <user> --password <password>

First, consider the following action (named calculator), which simply uses the JavaScript eval function to determine the result of a mathematical expression. Hence, all the action expects as input parameter is a string representing a valid mathematical expression:

function main(params) {
return { result: eval(params.operation) };
}

Next, enable the action as web action:

$ wsk action update calculator --web true
ok: updated action calculator

Next, use the API path /calculator, and the verb GET to point to the action:

$ wsk api create /calculator GET calculator
ok: created API /calculator GET for action /_/calculator
https://service.us.apiconnect.ibmcloud.com/gws/apigateway/api/8326f1d8a3dbc5afd14413a2682b7a78e17a55ee352f6c03f6be82718d69726e/calculator

Finally, try it out:

$ curl --request GET https://service.us.apiconnect.ibmcloud.com/gws/apigateway/api/8326f1d8a3dbc5afd14413a2682b7a78e17a55ee352f6c03f6be82718d69726e/calculator?operation=4*5{
"result": 20
}

Note that parameters that are passed via the query string become available in the params object passed into the action’s main function.

Also note that the same endpoint can be mapped to different actions by using different verbs (get, post, put, delete). Think of a typical CRUD endpoint, where a GET request may call an action to query data, a POST request an action to create/add data, and a DELETE request an action to delete data.

Mapping API endpoints to OpenWhisk actions using the OpenWhisk UI

Now, let’s examine how to do the same than before using the OpenWhisk UI (access from here: https://console.ng.bluemix.net/openwhisk/).

Open the OpenWhisk UI.
Select the API tab.
Click the Create an OpenWhisk API button (only visible if you haven’t created any API before).
As API name specify calculator2:

Creating a new API

Leave everything else as-is and click the Save button at the bottom of the screen.

On the next screen select the Definition tab from the navigation on the left of the screen.
Click the Create operation button.
As path specify calculator.
As action select the calculator action:

Defining a new operation

Leave everything else as-is and click the Save button at the bottom of the dialog. On the next screen do not forget to click the Save button at the bottom of the screen.

To find out about the URL to be used to invoke this operation switch to the API Explorer tab.
From the list at the left select the getCalculator entry and copy the GET URL shown:

Determining API endpoint URLs

Open a browser window, copy & paste the GET URL and append the query parameter ?operation=4*5.

You should be presented the result 4*5=20:

Additional features

To secure your API select the Definition tab from the navigation on the left of the screen.
Select the Require consuming applications to authenticate via API key option and leave all other settings as-is:

Forcing consuming applications to authenticate via AP key

Click the Save button at the bottom of the screen.

Now, when trying to call the endpoint again without authorizing you will end up with the following error:

$ curl --request GET https://service.us.apiconnect.ibmcloud.com/gws/apigateway/api/8326f1d8a3dbc5afd14413a2682b7a78e17a55ee352f6c03f6be82718d69726e/api/calculator?operation=4*5{"status":401,"message":"Error: Unauthorized"}

To be able to authenticate properly we first need to create an API key.
Therefore, switch to the Sharing tab from the navigation on the left of the screen.
Click the Create API Key button (next to API keys created by Bluemix users).
Specify a name for your new API Key like Test API key:

Creating an API key

Leave everything else as-is and click the Save button at the bottom of the screen.

Now, copy the API key that has been created and call your endpoint again like this:

$ curl --request GET https://service.us.apiconnect.ibmcloud.com/gws/apigateway/api/8326f1d8a3dbc5afd14413a2682b7a78e17a55ee352f6c03f6be82718d69726e/api/calculator?operation=4*5 --header 'X-IBM-Client-ID: <YOUR API KEY>'{
"result": 20
}

Next, to limit the call rate select the Definition tab from the navigation on the left of the screen again.
Select the Limit API call rate on a per-key basis option and set the limit to 2 calls per minute:

Enforcing call rates

Leave everything else as-is and click the Save button at the bottom of the screen.

Now, try to call the endpoint more often than two times per minute.
You should receive the following error:

$ curl --request GET https://service.us.apiconnect.ibmcloud.com/gws/apigateway/api/8326f1d8a3dbc5afd14413a2682b7a78e17a55ee352f6c03f6be82718d69726e/api/calculator?operation=4*5 --header X-IBM-Client-ID: <YOUR API KEY>'{"status":429,"message":"Error: Rate limit exceeded."}

Next, to force users to authenticate via OAuth select the Definition tab from the navigation on the left of the screen again.
Disable authentication via API key and rate limiting.
Select the Require end users to authenticate via OAuth social login option.
As provider select Facebook and leave all other settings as-is.

Now, when trying to call the endpoint again without authorizing you will end up with the following error:

$ curl --request GET https://service.us.apiconnect.ibmcloud.com/gws/apigateway/api/8326f1d8a3dbc5afd14413a2682b7a78e17a55ee352f6c03f6be82718d69726e/api/calculator?operation=4*5{"status":401,"message":"Error: No Authorization header provided"}

To authenticate properly call your endpoint like this:

$ curl --request GET https://service.us.apiconnect.ibmcloud.com/gws/apigateway/api/8326f1d8a3dbc5afd14413a2682b7a78e17a55ee352f6c03f6be82718d69726e/api/calculator?operation=4*5 --header 'authorization: <YOUR FACEBOOK USER TOKEN>' --header 'x-facebook-app-token: <YOUR FACEBOOK APP TOKEN>'{
"result": 20
}

Note that you need to create & obtain your Facebook credentials from here — following Facebook’s documentation: https://developers.facebook.com/

Finally, to analyze your APIs usage select the Summary tab from the navigation on the left of the screen and review the statistics:

API usage statistics

--

--