AWS: ApiGateway+Lambda的使用(CDK)

一、简介

Amazon API Gateway 是一项 AWS 服务,用于创建、发布、维护、监控和保护任意规模的 REST、HTTP 和 WebSocket API。主要解决服务治理,包含缓存、限流、熔断,还有路由、鉴权、聚合等功能。

AWS Lambda 是一项计算服务,可使您无需预配置或管理服务器即可运行代码。AWS Lambda 只在需要时执行您的代码并自动缩放,从每天几个请求到每秒数千个请求。您只需按消耗的计算时间付费 – 代码未运行时不产生费用。熟称“胶水代码”,可以和云上的大部分服务进行组合使用。

二、使用场景

API Gateway 的架构如下图所示,API Gateway 用作应用程序的“前门”,以便访问后端服务的数据、业务逻辑或功能,例如在 AWS Lambda 上运行的代码、任意 Web 应用程序或实时通信应用程序。

对于一个前后端分离的应用来说,如下使用场景非常适合于应用的“后端”:

  1. 浏览器发起一个后端的请求后
  2. API Gateway 用作API的“前门”,接收请求并进行路由转发,将请求转发给Lambda
  3. Lambda作为后台API,可以访问和操纵数据库。
  4. DynamoDB作为non-sql的数据库,用于存入业务数据。

在这里插入图片描述

三、Demo

本节目的:通过AWS CDK创建一个项目,以实现如下服务的部署:

  • 创建一个ApiGateway,添加一个路由,它纯用于路由的转发,这里以现成的百度首页为例,将请求访问https://<ApiGatewayUrl>/baidu时, 自动跳转到http://baidu.com页面。
  • 创建一个lambda方法,并将其添加到ApiGateway的一个新的路由之中,当用户使用Http-Method=GET访问https://<ApiGatewayUrl>/book/1时,能调到lambda方法。
  • 创建一个lambda方法,并将其添加到ApiGateway的一个新的路由之中,当用户使用Http-Method=POST访问https://<ApiGatewayUrl>/book时,能调到lambda方法。

1. 运行命令,创建一个CDK项目并使用vscode打开

mkdir apigateway_lambda-demo && cd apigateway_lambda-demo
cdk init -l typescript && code .

2. 填充stack的代码

lib/apigateway_lambda-demo-stack.ts 文件里填充如下代码:

import * as cdk from "@aws-cdk/core"; // 必须引入的包
import * as ec2 from "@aws-cdk/aws-ec2"; // for VPC
import * as apigatewayv2 from "@aws-cdk/aws-apigatewayv2"; // 使用api gateway
import * as lambda from "@aws-cdk/aws-lambda"; // 使用lambda

export class ApigatewayLambdaDemoStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // 通常VPC已经默认创建好了,这一步是为了寻找现有的VPC
    const vpc = ec2.Vpc.fromLookup(this, "Vpc", { isDefault: true });

    // 通常ApiGateway可以加两种类型的intergration,一是HttpProxyIntegration,作为代理进行路由转发,二是LambdaProxyIntegration,调用lambda
    // 创建第一个Integration,会跳转到百度首页
    const baiduHttpProxyIntergration = new apigatewayv2.HttpProxyIntegration({
      url: "https://baidu.com",
      method: apigatewayv2.HttpMethod.GET,
    });

    // 创建一个get method的lambda方法
    const getBookByIdHandler = new lambda.Function(this, "getBookByIdHandler", {
      runtime: lambda.Runtime.NODEJS_12_X,
      handler: "index.handler",
      code: lambda.Code.fromInline(`
        exports.handler = async function(event, context){
            return {
              statusCode: 200,
              body: 'your book id is:' + event.pathParameters.book_id
            }
        }
      `),
      // code: lambda.Code.fromAsset("./dist-website"), // 将本地文件夹dist-website上传到lambda中,可以是一个.zip文件或文件夹,不可以指定具体文件
    });

    // 创建一个LambdaProxyIntegration,具体的逻辑是上面的lambda方法
    const getBookByIdLambdaIntergation = new apigatewayv2.LambdaProxyIntegration(
      { handler: getBookByIdHandler }
    );

    // 创建一个post method的lambda方法
    const postBookHandler = new lambda.Function(this, "postBookHandler", {
      runtime: lambda.Runtime.NODEJS_12_X,
      handler: "index.handler",
      code: lambda.Code.fromInline(`
        exports.handler = async function(event, context){
            return {
              statusCode: 200,
              body: 'your book has been added'
            }
        }
      `),
    });

    // 创建一个LambdaProxyIntegration,具体的逻辑是上面的lambda方法
    const postBookHandlerLambdaIntergation = new apigatewayv2.LambdaProxyIntegration(
      { handler: postBookHandler }
    );

    // 创建一个ApiGateway
    const congApiGateway = new apigatewayv2.HttpApi(this, "congApiGateway", {
      corsPreflight: {
        // 设置跨域
        allowHeaders: ["Authorization"], // 允许http header中包含Authorization关键字
        allowMethods: [
          // 允许发送get/head/options/post请求
          apigatewayv2.HttpMethod.GET,
          apigatewayv2.HttpMethod.HEAD,
          apigatewayv2.HttpMethod.OPTIONS,
          apigatewayv2.HttpMethod.POST,
        ],
        allowOrigins: ["*"], // 允许所有的ip都能访问此url
        // maxAge: Duration.days(10), // 调用API前会选发送options请求,这里表示10天内可以直接调用API,而不用先发送options请求
      },
      defaultIntegration: baiduHttpProxyIntergration, // 设置默认的Intergration
    });

    // 向ApiGateway中添加路由规则,get请求
    congApiGateway.addRoutes({
      integration: baiduHttpProxyIntergration,
      path: "/baidu",
      methods: [apigatewayv2.HttpMethod.GET],
    });

    // 向ApiGateway中添加路由规则,get请求带参数
    congApiGateway.addRoutes({
      integration: getBookByIdLambdaIntergation,
      path: "/book/{book_id}",
      methods: [apigatewayv2.HttpMethod.GET],
    });

    // 向ApiGateway中添加路由规则,post请求
    congApiGateway.addRoutes({
      integration: postBookHandlerLambdaIntergation,
      path: "/book",
      methods: [apigatewayv2.HttpMethod.ANY], // 这里直接写成POST后,发起请求的时候不会成功,这里要写成ANY
    });

    // 发布ApiGateway,分别发布到dev开发环境和prod生产环境,如果不填stageName,默认的环境名为$default,在ApiGateway的URL后面可不用添加环境名。
    congApiGateway.addStage("development", {
      stageName: "dev",
      autoDeploy: true,
    });
    congApiGateway.addStage("production", {
      stageName: "prod",
      autoDeploy: true,
    });

    const apiGatewayUrl = `https://${congApiGateway.httpApiId}.execute-api.${
      cdk.Stack.of(this).region
    }.${cdk.Stack.of(this).urlSuffix}`;
    new cdk.CfnOutput(this, "defaultUrl", { value: `${apiGatewayUrl}/dev` });
    new cdk.CfnOutput(this, "baiduUrl", {
      value: `${apiGatewayUrl}/dev/baidu`,
    });
    new cdk.CfnOutput(this, "bookUrl", { value: `${apiGatewayUrl}/dev/book` });
  }
}

3. 运行部署命令

cdk deploy
# Outputs:
# ApigatewayLambdaDemoStack.baiduUrl = https://05y8wk26y4.execute-api.ap-east-1.amazonaws.com/dev/baidu
# ApigatewayLambdaDemoStack.bookUrl = https://05y8wk26y4.execute-api.ap-east-1.amazonaws.com/dev/book
# ApigatewayLambdaDemoStack.defaultUrl = https://05y8wk26y4.execute-api.ap-east-1.amazonaws.com/dev

# Stack ARN:
# arn:aws:cloudformation:ap-east-1:067379595472:stack/ApigatewayLambdaDemoStack/e1f457c0-23e2-11eb-a8bf-0a320f0cd704

4. 测试

# 跳转到了百度
/mnt/c/CongStudy/aws-cdk-demo/apigateway_lambda-demo$ curl -v https://05y8wk26y4.execute-api.ap-east-1.amazonaws.com/dev/baidu
*   Trying 18.166.18.216...
* Connected to 05y8wk26y4.execute-api.ap-east-1.amazonaws.com (18.166.18.216) port 443 (#0)
* found 148 certificates in /etc/ssl/certs/ca-certificates.crt
* found 592 certificates in /etc/ssl/certs
* ...
> GET /dev/baidu HTTP/1.1
> Host: 05y8wk26y4.execute-api.ap-east-1.amazonaws.com
> User-Agent: curl/7.47.0
> Accept: */*
>
< HTTP/1.1 302 Found
< Date: Wed, 11 Nov 2020 06:02:54 GMT
< Content-Type: text/html
< Content-Length: 161
< Connection: keep-alive
< server: bfe/1.0.8.18
< apigw-requestid: V1C2Di_pHUYEPpA=
< location: http://www.baidu.com
< ...
# 发送get请求带参数
/mnt/c/CongStudy/aws-cdk-demo/apigateway_lambda-demo$ curl https://05y8wk26y4.execute-api.ap-east-1.amazonaws.com/dev/book/1
your book id is:1

# 发送post请求
/mnt/c/CongStudy/aws-cdk-demo/apigateway_lambda-demo$ curl -XPOST https://05y8wk26y4.execute-api.ap-east-1.amazonaws.com/dev/book
your book has been added

5. 在console中验证

xxx

在这里插入图片描述

6. 销毁创建的所有服务以节省成本

cdk destroy

四、参考链接

  1. AWS Api Gateway官网
  2. aws cdk api gateway v2
  3. aws cdk lambda
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要在AWS云上使用Java,您可以使用Lambda函数来运行Java代码。Lambda函数是一种无服务器计算服务,可以让您运行代码而无需管理服务器。您可以将Java代码打包成一个JAR文件,并将其上传到Lambda函数中。然后,您可以使用API Gateway来创建API端点,以便您的应用程序可以与Lambda函数通信。 以下是使用CloudFormation创建Lambda函数和API Gateway的步骤: 1. 编写Lambda函数代码,并将其打包成JAR文件。您可以使用Maven或Gradle等构建工具来构建和打包代码。 2. 使用CloudFormation模板定义Lambda函数和API Gateway。下面是一个简单的模板示例: ``` Resources: MyLambdaFunction: Type: AWS::Lambda::Function Properties: Code: S3Bucket: my-bucket S3Key: my-lambda-function.jar Handler: com.example.MyLambdaFunctionHandler::handleRequest Role: !GetAtt MyLambdaExecutionRole.Arn Runtime: java8 MyApiGateway: Type: AWS::ApiGateway::RestApi Properties: Name: my-api-gateway MyApiGatewayResource: Type: AWS::ApiGateway::Resource Properties: ParentId: !GetAtt MyApiGateway.RootResourceId PathPart: my-resource MyApiGatewayMethod: Type: AWS::ApiGateway::Method Properties: RestApiId: !Ref MyApiGateway ResourceId: !Ref MyApiGatewayResource HttpMethod: GET AuthorizationType: NONE Integration: Type: AWS_PROXY IntegrationHttpMethod: POST Uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyLambdaFunction.Arn}/invocations MyLambdaExecutionRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: lambda.amazonaws.com Action: sts:AssumeRole Policies: - PolicyName: MyLambdaExecutionPolicy PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - logs:CreateLogGroup - logs:CreateLogStream - logs:PutLogEvents Resource: arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/my-lambda-function:* ``` 该模板定义了一个Lambda函数,一个API Gateway,一个API Gateway资源和一个API Gateway方法。API Gateway方法使用AWS_PROXY集成类型,以便将请求传递给Lambda函数。 3. 使用CloudFormation部署模板。您可以使用AWS CLI或AWS管理控制台等工具来部署模板。 4. 测试API端点。使用API Gateway提供的URL测试API端点,并确保它可以正常工作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值