xp-forge/lambda-ws

XP 框架的 AWS Lambda Web 服务

v2.3.0 2024-05-20 10:38 UTC

README

Build status on GitHub XP Framework Module BSD Licence Requires PHP 7.0+ Supports PHP 8.0+ Latest Stable Version

使用XP 网络应用在 AWS Lambda 上运行,通过API GatewayLambda 函数 URL。与其它实现不同,这个库不是启动 PHP-FPM,而是直接运行请求,从而减少了小于 1ms 的开销。

示例

将此代码放入名为 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');
    }];
  }
}

请求上下文通过名为 request 的请求值传入,并包含一个RequestContext 实例。lambda 上下文通过 context 传入。

要运行现有网络应用,从 routes() 方法返回你的 web.Application 子类的一个实例。

开发和测试

要本地运行 HTTP API,此库通过包装器与 xp-forge/web 集成。

$ 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

# ...

通过添加 -m develop,这些可以在开发网络服务器上运行。

设置和部署

按照xp-forge/lambda README 上的说明来创建运行时层、服务角色以及 Lambda 函数本身。接下来,按照以下方式创建函数 URL

$ aws lambda create-function-url-config \
  --function-name greet \
  --auth-type NONE \
  --invoke-mode RESPONSE_STREAM

此命令将返回 URL。

调用

您可以在浏览器中打开 HTTP 端点或使用 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

部署更改

在最初创建 Lambda 后,您可以按照以下方式更新其代码

$ xp lambda package Greet.class.php
$ aws lambda update-function-code \
  --function-name greet \
  --zip-file fileb://./function.zip \
  --publish

流式传输

此库实现了 AWS 在 2023 年 4 月宣布的 HTTP 响应流,提高了网络应用的 TTFB 和内存消耗。响应流对设置了 invoke 模式为 RESPONSE_STREAM 的 Lambda 函数 URL 可用。

HttpStreaming 基类继承,而不是从 HttpApi 继承

use com\amazon\aws\lambda\HttpStreaming;

class Greet extends HttpStreaming {

  public function routes($env) {
    /* Shortened for brevity */
  }
}

接下来,部署更改,然后更新函数配置

$ aws lambda update-function-url-config --function-name greet --invoke-mode RESPONSE_STREAM

请求上下文

通过 request 值传入的请求上下文定义如下

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
}

另请参阅