Run XP web applications on AWS lambda using API Gateway or Lambda Function URLs. Unlike other implementations, this library does not spawn PHP-FPM but runs requests directly, resulting in an overhead of less than 1ms.
Put this code in a file called Greet.class.php:
use com\amazon\aws\lambda\HttpIntegration;
class Greet extends HttpIntegration {
/**
* Returns routes
*
* @param web.Environment $env
* @return web.Application|web.Routing|[:var]
*/
public function routes($env) {
return ['/' => function($req, $res) {
$greeting= sprintf(
'Hello %s from PHP %s on stage %s @ %s',
$req->param('name') ?? $req->header('User-Agent') ?? 'Guest',
PHP_VERSION,
$req->value('request')->stage,
$req->value('context')->region
);
$res->answer(200);
$res->send($greeting, 'text/plain');
}];
}
}
The request context is passed into a request value named request and contains a RequestContext instance. The lambda context is passed in context.
To run existing web applications, return an instance of your web.Application
subclass from the routes() method.
To run the HTTP APIs locally, this library integrates with xp-forge/web via a wrapper:
$ xp web lambda Greet
@xp.web.srv.Standalone(HTTP @ peer.ServerSocket(Resource id #124 -> tcp://127.0.0.1:8080))
Serving prod:Lambda<Greet>[] > web.logging.ToConsole
════════════════════════════════════════════════════════════════════════
> Server started: http://localhost:8080 in 0.057 seconds
Sat, 18 Nov 2023 12:19:32 +0100 - PID 18668; press Ctrl+C to exit
# ...
By adding -m develop
, these can be run in the development webserver.
Follow the steps shown on the xp-forge/lambda README to create the runtime layer, the service role and the lambda function itself. Next, create the function URL as follows:
$ aws lambda create-function-url-config \
--function-name greet \
--auth-type NONE \
--invoke-mode RESPONSE_STREAM
The URL will be returned by this command.
You can either open the HTTP endpoint in your browser or by using curl:
$ curl -i https://XXXXXXXXXX.lambda-url.eu-central-1.on.aws/?name=$USER
Date: Sun, 18 Jun 2023 20:00:55 GMT
Content-Type: text/plain
Transfer-Encoding: chunked
Connection: keep-alive
x-amzn-RequestId: 3505bbff-e39e-42d3-98d7-9827fb3eb093
x-amzn-Remapped-content-length: 59
Set-Cookie: visited=1687118455; SameSite=Lax; HttpOnly
X-Amzn-Trace-Id: root=1-648f6276-672c96fe6230795d23453441;sampled=0;lineage=83e616e2:0
Hello timmf from PHP 8.2.7 on stage $default @ eu-central-1
After having initially created your lambda, you can update its code as follows:
$ xp lambda package Greet.class.php
$ aws lambda update-function-code \
--function-name greet \
--zip-file fileb://./function.zip \
--publish
This library implements HTTP response streaming as announced by AWS in April 2023, improving TTFB and memory consumption of web applications. Response streaming is available for lambda function URLs which have their invoke mode set to RESPONSE_STREAM.
Inherit from the HttpStreaming base class instead of HttpApi:
use com\amazon\aws\lambda\HttpStreaming;
class Greet extends HttpStreaming {
public function routes($env) {
/* Shortened for brevity */
}
}
Next, deploy the change, then update the function configuration:
$ aws lambda update-function-url-config --function-name greet --invoke-mode RESPONSE_STREAM
The request context passed via the request value is defined as follows:
public class com.amazon.aws.lambda.RequestContext implements lang.Value {
public string $accountId
public string $apiId
public string $domainName
public string $domainPrefix
public string $requestId
public string $routeKey
public string $stage
public util.Date $time
public [:string] $http
public function __construct(array $context)
public function toString(): string
public function hashCode(): string
public function compareTo(var $value): int
}