Relative Links with IBM Cloud API Gateway
Get the requested URL with JavaScript
Here’s a very simple prototype JavaScript action showing how to grab the URL that this action was requested with, and both log and return it:
function main(params) { var base_url = params['__ow_headers']['x-forwarded-url']; console.log("Base URL: " + base_url); return {body: "New item at " + base_url + "/42"}; } exports.main = main;
This shows how to find the base_url
that this request came in on. My code is deployed to a url-demo
package with this command:
bx wsk action update --kind nodejs:8 --web raw url-demo/js index.js
This creates the action, indicates which runtime to use (nodejs:8
) and also sets the action up with --web raw
which means that we can access the headers, body, method, query and path of the incoming request, without any additional parsing. There are also helper options that, for example, will parse incoming JSON but I prefer to see and parse the request as it arrived and know where all my data came from!
To set up the web routing, we use the API Gateway:
bx wsk api create /demo-js GET url-demo/js --response-type http
This command returns a URL that we can then call, either with cURL or simply by pasting it into your browser. The response will show the same URL with /42
appended (which you probably guessed from the code above!).
Get the requested URL with PHP
Since I’m writing a microservice in a bunch of different programming languages, here’s the same example again for PHP. First the code for the function:
<?php
function main(array $params) : array
{
$base_url = params['__ow_headers']['x-forwarded-url'];
var_dump("Base URL: " . $base_url);
return ["body" => "New item at " . $base_url . "/42"];
}
Next the commands to deploy the serverless action and set an API Gateway endpoint to talk to it:
bx wsk action update --kind php:7.1 --web raw url-demo/php index.php
bx wsk api create /demo-php GET url-demo/php --response-type http
Exactly as before, this pushes our code to the cloud as a serverless action, and then sets up an API route to point to it. The second command returns a URL, you can request it and see output that uses the requested URL as part of it.
This feature makes it easier to offer sensible pagination, relative links and other API goodness from the IBM Cloud Functions and API Gateway projects I work on. I like it a lot and hopefully these examples will be useful to anyone looking to build a similar project themselves.
Note that once you have added an additional segment to the `x-forwarded-for` value, then the next request will have that segment in its own `x-forwarded-for` value. i.e. `x-forwarded-for` contains the full URL that was requested by the client
For example. Let’s say that you start with an `x-forwarded-for` of `https://example.com/foo/bar/url-demo/php` and you respond with the new item’s URL of `https://example.com/foo/bar/url-demo/php/42`. When the client requests the new URL, the `x-forwarded-for` will contain the `https://example.com/foo/bar/url-demo/php/42` which is not the original `base_url`.
You can look in `params[‘__ow_path’]` to find this addition and so remove it from `x-forwarded-for` to get back to your original `base_url`.
Pingback: Using Fractal as your OpenWhisk API’s view layer – Rob Allen's DevNotes
Pingback: Using Fractal as your OpenWhisk API's view layer - webdev.am