Using Composer with Serverless & OpenWhisk
Every PHP project I write has dependencies on components from Packagist and my Serverless OpenWhisk PHP projects are no different. It turns out that adding Composer dependencies is trivial.
Let’s create a simple action that converts a number to it’s string form. e.g. 123 becomes one hundred and twenty three. We’ll start with our simple ow-php-hello project from my earlier article and add a new function to serverless.yml:
functions:
n2w:
handler: n2w.main
Our handler is n2w.main, so we need a n2w.php file with our main() function:
<?php
use NFNumberToWord\NumberToWords;
function main(array $args) : array
{
if (!isset($args['number'])) {
return ['error' => 'Please supply a number.'];
}
$number = (int)($args['number']);
$words = (new NumberToWords)->toWords($number);
return [
'Result' => $words,
];
}
This action uses NFNumberToWord which is available from Packagist so we add it via composer:
$ composer require nineteenfeet/nf-number-to-word
This creates our vendor directory in the top level of our project and we can now deploy:
$ sls deploy
As you read the output, you’ll notice that it has created two actions: ow-php-hello-dev-hello and ow-php-hello-dev-n2w. We can now test our new n2w action:
$ sls invoke -f n2w -d '{"number": 123}'
This generates our expected output:
{
"result": "one hundred and twenty-three"
}
It all works as you’d expect!
A note on packaging
If you look in the .serverless directory, you’ll discover that Serverless has created a single ow-php-hello.zip which contains all the code from the project. This is then uploaded to both actions.
I prefer to have the minimum amount of files in my action as it loads slightly faster and is just cleaner. To control this, we use the package configuration directive in serverless.yml.
package:
individually: true
This will ensure that we create a separate .zip file for each action: hello.zip and n2w.zip.
To control which files are included in each zip file we can use the include and exclude directives. This is how I like to set it up in my serverless.yaml:
package:
individually: true
exclude:
- "*"
include:
- "vendor/**"
functions:
hello:
handler: handler.hello
annotations:
web-export: true
package:
include:
- handler.php
n2w:
handler: n2w.main
annotations:
web-export: true
package:
include:
- n2w.php
At the global package level, I exclude all files and then include Composer’s vendor directory. Then, for each function, I include the specific PHP files required.
This results in the action zip files containing just the code required for running the action which is how I like it.
Fin
As you can see composer dependencies work just as you would expect when using Serverless with the OpenWhisk PHP plugin. Exactly how it should be!
thanks