学习使用 AWS API Gateway V2

关于 AWS API Gateway V1, 写过一篇笔记 Lambda + API Gateway 创建需 API Key 验证的 API。 AWS 又推出了 API Gateway V2(服务管理/理解层面), 它同样可以用来作 HTTP-PROXY 调用 REST API, WebSocket; AWS-PROXY 调用 Lambda, 还能直接调用 AWS 的其他服务,如 StepFunction, SQS 等。

但是  API Gateway V2 把 V1 中的 API Key 验证功能去掉了,这有点为了赚钱耍无赖了,先前是 API Key 验证不过时不会调用 Lambda, 现在可用 Lambda 来验证 API 调用,也就是不管 API Key 对与不对,都会去调用 Lambda 从而实现从你的帐户上扣钱的功能。

在 V1 中创建整套服务的过程基本是  Resource -> Method -> Integration -> Stage。而在 V2 中的过程是 Integration -> Route -> Stage, 把 Resource 和 Method  合而为一,比如 Route Key 写成 GET /users.

下面照旧以 Terraform 的方式来叙述使用 API Gateway V2 如何实现 HTTP 代理,调用 Lambda, 及使用 AWS 服务(以 SQS 为例),或与 VPC 内部的服务集成。首先是一个基本的框架,含 API 本身和 Stage

执行后回到 AWS 的 Web 控制台看到的就是 API Gateway V2 的界面,AWS 并不会告诉你这是 V2 的界面,但可留意到左边的菜单不一样了,由 V1 的 API/Resources 变成了 Develop/Routes, 其他操作菜单的也都有了变化

Stage 帮我们产生了一个 Invoke URL, 比如 Stage 为 stg, 得到一个类似这样的 URL https://fsoaey6ra4.execute-api.us-east-1.amazonaws.com/stg. 接着就看各种功能的实现

API Gateway V2 与 Lambda 的集成

基本要素与 API Gateway V1 保持一致,外部访问用 GET/POST/PUT 等,但 API Gateway 内部与 Lambda 的通信是用 POST 的,同时要具备相应的权限,因为在 Lambda 方面同样是加上相应的 API Gateway 触发器。

Lambda 资源的创建这里省略了,上面的 route_key 需要更稍加理解,它是 V1 中的 method resource 的合成表示方式,比如 POST /lambda/users 等。甚至还能用  $default, 表示对 Invoke URL 任何形式的请求, 但对于集成 Lambda 的 Gateway, 设置 route_key 为 $default 的话,aws_lambda_permission 中的 source_arn 将变得难以配置。

配置好后,用下面的方式就能调用 Lambda

$ curl https://fsoaey6ra4.execute-api.us-east-1.amazonaws.com/stg/lambda/users/1234

在 Lambda 中可打印出完整的 event, 可帮助我们理解怎么传递,及解析请求数据的。

API Gateway V2 作为 HTTP(S) 代理

我们可完全用 API Gateway V2 作为一个 HTTP(S) 的代理,发往 API Gateway 上的所有请求全部转发到后端 HTTP(S) 服务

上面 integration_type 和 route_key 中的 method 都是 ANY, 并且由 ANY /go/{proxy+}ANY http://example.com/{proxy} 产生的效果就是

  1. GET https://fsoaey6ra4.execute-api.us-east-1.amazonaws.com/stg/go/   -> GET http://examle.com/
  2. POST https://fsoaey6ra4.execute-api.us-east-1.amazonaws.com/stg/go/aaa/bbb  -> POST http://example.com/aaa/bbb
  3. ......

也可以显式的逐个指定 route_key, 如下面那样随意发挥

route_key = "GET /abc", integration_method="POST", integration_url = "http://example.com/xyz/kk"

但是必须清楚一点,API Gateway 的  HTTP_PROXY 只能直接与 public 的 HTTP(S) 集成,也就是你在 VPC 内部创建了的 EC2 或  ECS 启动的 HTTP(S) 服务不能直接访问,必须外加一个 ELB 和 VPC Link 才能与 API Gateway 连接起来,后面会讲到。

API Gateway V2 与  AWS 服务的集成(以 SQS 为例)

API Gateway V2 除了调用 Lambda 外,还能调用 AWS 的其他服务,下面以 SQS-SendMessage 为例

如果 IAM role  的权限没问题的话,下面的请求将能发送一条 SQS 消息到队列中

$ curl -X POST -H "queueUrl:https://sqs.us-east-1.amazonaws.com/123456789088/test-queue" \
    -H "content-type:application/json" \
    https://fsoaey6ra4.execute-api.us-east-1.amazonaws.com/stg/sqs \
    --data '{"message": "your message body here"}'

integration_typeAWS_PROXY 时,integration_subtype 要以选择以下其中一个:

  1. EventBridge-PutEvents
  2. SQS-SendMessage
  3. SQS-ReceiveMessage
  4. SQS-DeleteMessage
  5. SQS-PurgeQueue
  6. AppConfig-GetConfiguration
  7. Kinesis-PutRecord
  8. StepFunctions-StartExecution
  9. StepFunctions-StartSyncExecution
  10. StepFunctions-StopExecution

详情见 Integration subtype reference

关于 request_parameters,response_parameters 的映射可参考 Transforming API requests and responses

另外,如果在调用 API Gateway 时出现无法理解的错误时,请启用 API Gateway 的 Logging, 并在 Log format 中按相同规则添加以下三个字段

  1. $context.integrationErrorMessage
  2.  $context.error.message
  3. $context.error.responseType

更多 API Gateway 日志相关的字段,请见 Customizing HTTP API access logs

API Gateway V2 连接 Private ELB

这样做的好处估计是用 Private ELB 提供多数的服务内部使用,其中少数 API 需要暴露给外部,所以就以 API Gateway 作为桥梁。为此,首先需创建一个 VPC Link, 自然就要提供相应的 Security Group, Subnet,以及需要被连接的 Private ELB 的监听器的 ARN

与前面的 HTTP_PROXY 大致类似,不同的就是 connection_type 为 VPC_LINK。完后,访问 Invoke URL 的所有类型的请求悉数转发到了 ELB 监听器上了。

API Gateway 使用 VPC_LINK 就能打通与 VPC 内部的服务,在网络通路上把请求代理到 EC2 机器上是没问题的,或可借助于 Route 53 解析到某个 Private 的 EC2 上,但它没提供这样的功能,因为跳过 ELB 的话估计会少赚些钱。

总结

配置 API Gateway 时很容易碰到各种问题,比使用 ELB + ECS 碰到的问题会多得多,因为 API Gateway 与后端服务之间对我们来说是个黑盒子。

API Gateway V2 配置的重点在 aws_apigatewayv2_integration, 还有许多参数前面尚未提及,如代理时的 passthrough_behavior. payload_format_version 2.0 比 1.0 更宽松,Lambda 中返回的字符串自动封装。还有 response_parameters 等等。

API Gateway V2 与 V1 相比而言就只觉得写 route_key 比单独的定义每一个 Resource, Method 要简单,其实质好像没有什么变化。所以在 AWS Web 控制台并不标识出是 V2 还是 V1 大概也就是这个原因, 因为对于用户而言还真就是控制台 UI 的变化而已。

其他的, API Gateway V2 集成 WebSocket 或许还有些新的内容,实际工作中还未真正用过 WebSocket,故未作深究。


[2022-01-10]:API Gateway V1 和 V2 的 Lambda 请求 event 数据格式是不一样的,以下分别是 V1 和 V2 的 event

API Gateway V1 Lambda event:

API Gateway V2 Lambda event

Lambda 在处理 Event 时要注意,关于 Key 的大小写,可以把 event 转换为 CaseInsensitiveDict 来保持兼容

确定请求资源也不一样,V1 中取 httpMethod 和 resource 组合,V2 中要取 routeKey。


类别: AWS. 标签: , . 阅读(156). 订阅评论. TrackBack.
guest
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x