Pragmatism in the real world

Using API Gateway with Serverless & OpenWhisk

As with all serverless offerings OpenWhisk offers an API Gateway to provide HTTP routing to your serverless actions. This provides a number of advantages over web actions, the most significant of which are routing based on HTTP method, authentication and custom domains (in IBM Cloud).

Creating routes with the wsk CLI

To route to an action using API Gateway, you first need to make your action a web action first:

$ wsk action update todo-backend/listTodos listTodos.php --web raw

(You can also use --web true, if you want the automatic decoding of post bodies and query parameters.)

Now that we have a web action we can create the API route:

$ wsk api create /todos GET todo-backend/listTodos --apiname todo-backed --response-type http

This creates the HTTP endpoint which is a massively long URL that starts with https:// and ends with /todos.

Creating routes with Serverless

All these CLI commands are tedious and so clearly they need automating. One easy way to do this is to use Serverless Framework as I’ve discussed before.

To create an API Gateway endpoint for an action, we add an http event to the action definition in serverless.yml:

list-todos:
  handler: src/actions/listTodos.main
  name: "todo-backend/list-todos"
  events:
    - http:
        path: /todos
        method: get
        resp: http

The handler tells Serverless that the code for this action is in the main() function within listTodos.php and is required. We use the name parameter to set the package for this action (todo-backend.

Finally, to the list of events, we add a http section where we set following:

path The URL for the end point
method The HTTP method for this end point
resp The web action content type. Set this to http so that you can send back the status code and any custom headers

Sending the response from the action

If you use the http web action content type, you must return a dictionary with these three keys:

statusCode The status code (100-599)
headers A dictionary of headers
body The body content. If this is a dictionary, then it will be automatically converted to JSON for you.

For example, in listTodos.php, we might have this:

<php

/**
 * GET /todos
 */
function main(array $args) : array
{
    $container = new \App\AppContainer($args);
    $mapper = $container[\Todo\TodoMapper::class];

    $todos = $mapper->fetchAll();

    return [
        'statusCode' => 200,
        'headers' => [
            'X-Clacks-Overhead' => 'GNU Terry Pratchett,
        ]
        'body' => $todos->toArray(),
    ];
}

In this particular case, we don’t really need to set the statusCode as the default is 200 anyway. We also don’t need to set the Content-Type to application/json as this is also done for us as OpenWhisk has converted our array to JSON.

Fin

Adding API Gateway end points to an OpenWhisk API using Serverless is a few lines of configuration and then we can let the tool do the leg work of setting up OpenWhisk for us.

One thought on “Using API Gateway with Serverless & OpenWhisk

Comments are closed.