使用AWS API Gateway,AWS Lambda和Couchbase的微服务

到目前为止, 此博客已经解释了无服务器应用程序的以下概念:

无服务器系列中的第三个博客将解释如何使用Amazon API Gateway,AWS Lambda和Couchbase创建简单的微服务。

阅读以前的博客以获取有关AWS Lambda的更多上下文。

Amazon API Gateway是一项完全托管的服务,使开发人员可以轻松地创建,发布,维护,监控和保护各种规模的API。 Amazon API Gateway处理与接受和处理多达数十万个并发API调用有关的所有任务,包括流量管理,授权和访问控制,监视以及API版本管理。

以下是此体系结构中的关键组件:

  • 客户端可以是curl,AWS CLI,Postman客户端或可以调用REST端点的任何其他工具/ API。
  • API网关用于配置API。 顶级资源位于path /books 。 为该资源发布了HTTP GETPOST方法。
  • 每个API都会触发Lambda函数。 创建了两个Lambda函数,用于列出所有可用book-create的书籍book-list功能,以及用于创建新书籍的书籍book-create功能。
  • Couchbase在EC2中用作持久性存储。 所有JSON文档都将从该数据库中存储和检索。

让我们开始吧!

创建IAM角色

IAM角色将具有策略和信任关系,这些策略和信任关系将允许该角色在API网关中使用并执行Lambda函数。

让我们创建一个新的IAM角色:

aws iam create-role \
--role-name microserviceRole \
--assume-role-policy-document file://./trust.json

--assume-role-policy-document定义了信任关系策略文档,该文档授予实体担任角色的权限。 trust.json位于github.com/arun-gupta/serverless/blob/master/aws/microservice/trust.json ,看起来像:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": [
          "lambda.amazonaws.com",
          "apigateway.amazonaws.com"
        ]
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

这种信任关系允许Lambda函数和API网关在执行期间担当此角色。

与此角色相关联的策略为:

aws iam put-role-policy \
--role-name microserviceRole \
--policy-name microPolicy \
--policy-document file://./policy.json

policy.json位于github.com/arun-gupta/serverless/blob/master/aws/microservice/policy.json ,看起来像:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "logs:*"
      ],
      "Resource": "arn:aws:logs:*:*:*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "apigateway:*"
      ],
      "Resource": "arn:aws:apigateway:*::/*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "execute-api:Invoke"
      ],
      "Resource": "arn:aws:execute-api:*:*:*"
    },
    {
      "Effect": "Allow",
      "Action": [
          "lambda:*"
      ],
      "Resource": "*"
    }
  ]
}

这种慷慨的策略允许对CloudWatch中为所有资源生成的日志具有任何权限。 另外,它允许对所有资源的所有Lambda和API网关权限。 通常,仅将所需的策略分配给特定资源。

创建Lambda函数

使用AWS Lambda和Java的无服务器FaaS中介绍了创建Lambda函数的详细步骤。 让我们根据需要创建两个Lambda函数:

aws lambda create-function \
--function-name MicroserviceGetAll \
--role arn:aws:iam::598307997273:role/microserviceRole \
--handler org.sample.serverless.aws.couchbase.BucketGetAll \
--zip-file fileb:///Users/arungupta/workspaces/serverless/aws/microservice/microservice-http-endpoint/target/microservice-http-endpoint-1.0-SNAPSHOT.jar \
--description "Microservice HTTP Endpoint - Get All" \
--runtime java8 \
--region us-west-1 \
--timeout 30 \
--memory-size 1024 \
--environment Variables={COUCHBASE_HOST=ec2-52-53-193-176.us-west-1.compute.amazonaws.com} \
--publish

此功能中需要注意的几个关键项目是:

  • 此处明确指定了在上一步中创建的IAM角色microserviceRole
  • 处理程序是org.sample.serverless.aws.couchbase.BucketGetAll类。 此类查询使用COUCHBASE_HOST环境变量定义的Couchbase数据库。

创建第二个Lambda函数:

aws lambda create-function \
--function-name MicroservicePost \
--role arn:aws:iam::598307997273:role/microserviceRole \
--handler org.sample.serverless.aws.couchbase.BucketPost \
--zip-file fileb:///Users/arungupta/workspaces/serverless/aws/microservice/microservice-http-endpoint/target/microservice-http-endpoint-1.0-SNAPSHOT.jar \
--description "Microservice HTTP Endpoint - Post" \
--runtime java8 \
--region us-west-1 \
--timeout 30 \
--memory-size 1024 \
--environment Variables={COUCHBASE_HOST=ec2-52-53-193-176.us-west-1.compute.amazonaws.com} \
--publish

此函数的处理程序是org.sample.serverless.aws.couchbase.BucketPost类。 此类在由COUCHBASE_HOST环境变量标识的Couchbase数据库中创建一个新的JSON文档。

这些类的完整源代码位于github.com/arun-gupta/serverless/tree/master/aws/microservice/microservice-http-endpoint

API网关资源

使用Amazon API Gateway创建API并进行测试构建API以公开Lambda函数,提供了有关如何使用API​​ Gateway和Lambda函数来构建强大的后端系统的详细步骤和说明。 如果您想减少追踪,此博客将快速介绍这些步骤。

让我们创建API网关资源。

  • 第一步是创建一个API:
aws apigateway \
create-rest-api \
--name Book

输出显示为:

{
    "name": "Book", 
    "id": "lb2qgujjif", 
    "createdDate": 1482998945
}

id属性的值为API ID。 在我们的例子中,这是lb2qgujjif

  • 查找创建的API的ROOT ID,这是下一次AWS CLI调用所必需的:
aws apigateway get-resources --rest-api-id lb2qgujjif

显示输出:

{
    "items": [
        {
            "path": "/", 
            "id": "hgxogdkheg"
        }
    ]
}

id属性的值为ROOT ID。 这也是顶级资源的父ID。

  • 创建资源
aws apigateway create-resource \
--rest-api-id lb2qgujjif \
--parent-id hgxogdkheg \
--path-part books

显示输出:

{
    "path": "/books", 
    "pathPart": "books", 
    "id": "vrpkod", 
    "parentId": "hgxogdkheg"
}

id属性的值是RESOURCE ID。

API ID和RESOURCE ID用于后续的AWS CLI调用。

API网关POST方法

现在已经创建了资源,让我们在该资源上创建HTTP POST方法。

  • 创建一个POST方法
aws apigateway put-method \
--rest-api-id lb2qgujjif \
--resource-id vrpkod \
--http-method POST \
--authorization-type NONE

查看响应:

{
    "apiKeyRequired": false, 
    "httpMethod": "POST", 
    "authorizationType": "NONE"
}
  • 将Lambda函数设置为POST方法的目标:
aws apigateway put-integration \
--rest-api-id lb2qgujjif \
--resource-id vrpkod \
--http-method POST \
--type AWS \
--integration-http-method POST \
--uri arn:aws:apigateway:us-west-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-west-1:<act-id>:function:MicroservicePost/invocations

确保将<act-id>替换为您的AWS账户ID。 这里也使用上一部分的API ID和资源ID。 --uri用于指定集成输入的URI。 URI的格式是固定的。 此CLI将结果显示为:

{
    "httpMethod": "POST", 
    "passthroughBehavior": "WHEN_NO_MATCH", 
    "cacheKeyParameters": [], 
    "type": "AWS", 
    "uri": "arn:aws:apigateway:us-west-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-west-1:<act-id>:function:MicroservicePost/invocations", 
    "cacheNamespace": "vrpkod"
}
  • 设置POST方法响应的content-type
aws apigateway put-method-response \
--rest-api-id lb2qgujjif \
--resource-id vrpkod \
--http-method POST \
--status-code 200 \
--response-models "{\"application/json\": \"Empty\"}"

查看响应:

{
    "responseModels": {
        "application/json": "Empty"
    }, 
    "statusCode": "200"
}
  • 设置POST方法集成响应的content-type
aws apigateway put-integration-response \
--rest-api-id lb2qgujjif \
--resource-id vrpkod \
--http-method POST \
--status-code 200 \
--response-templates "{\"application/json\": \"Empty\"}"

查看响应:

{
    "statusCode": "200", 
    "responseTemplates": {
        "application/json": "Empty"
    }
}
  • 部署API
aws apigateway create-deployment \
--rest-api-id lb2qgujjif \
--stage-name test

看到回应

{
    "id": "9wi991", 
    "createdDate": 1482999187
}
  • 授予权限以允许API网关调用Lambda函数:
aws lambda add-permission \
--function-name MicroservicePost \
--statement-id apigateway-test-post-1 \
--action lambda:InvokeFunction \
--principal apigateway.amazonaws.com \
--source-arn "arn:aws:execute-api:us-west-1:<act-id>:lb2qgujjif/*/POST/books"

此外,向部署的API授予权限:

aws lambda add-permission \
--function-name MicroservicePost \
--statement-id apigateway-test-post-2 \
--action lambda:InvokeFunction \
--principal apigateway.amazonaws.com \
--source-arn "arn:aws:execute-api:us-west-1:<act-id>:lb2qgujjif/test/GET/books"
  • 测试API方法:
aws apigateway test-invoke-method \
--rest-api-id lb2qgujjif \
--resource-id vrpkod \
--http-method POST \
--path-with-query-string "" \
--body "{\"id\": \"1\", \"bookname\": \"test book\", \"isbn\": \"123\", \"cost\": \"1.23\"}"

查看响应:

{
    "status": 200, 
    "body": "Empty", 
    "log": "Execution log for request test-request\nThu Dec 29 08:16:05 UTC 2016 : Starting execution for request: test-invoke-request\nThu Dec 29 08:16:05 UTC 2016 : HTTP Method: POST, Resource Path: /books\nThu Dec 29 08:16:05 UTC 2016 : Method request path: {}\nThu Dec 29 08:16:05 UTC 2016 : Method request query string: {}\nThu Dec 29 08:16:05 UTC 2016 : Method request headers: {}\nThu Dec 29 08:16:05 UTC 2016 : Method request body before transformations: {\"id\": \"1\", \"bookname\": \"test book\", \"isbn\": \"123\", \"cost\": \"1.23\"}\nThu Dec 29 08:16:05 UTC 2016 : Endpoint request URI: https://lambda.us-west-1.amazonaws.com/2015-03-31/functions/arn:aws:lambda:us-west-1:598307997273:function:MicroservicePost/invocations\nThu Dec 29 08:16:05 UTC 2016 : Endpoint request headers: {x-amzn-lambda-integration-tag=test-request, Authorization=****************************************************************************************************************************************************************************************************************************************************************************************************************************************c8bb85, X-Amz-Date=20161229T081605Z, x-amzn-apigateway-api-id=lb2qgujjif, X-Amz-Source-Arn=arn:aws:execute-api:us-west-1:598307997273:lb2qgujjif/null/POST/books, Accept=application/json, User-Agent=AmazonAPIGateway_lb2qgujjif, Host=lambda.us-west-1.amazonaws.com, X-Amz-Content-Sha256=559d0296d96ec5647eef6381602fe5e7f55dd17065864fafb4f581d106aa92f4, X-Amzn-Trace-Id=Root=1-5864c645-8494974a41a3a16c8d2f9929, Content-Type=application/json}\nThu Dec 29 08:16:05 UTC 2016 : Endpoint request body after transformations: {\"id\": \"1\", \"bookname\": \"test book\", \"isbn\": \"123\", \"cost\": \"1.23\"}\nThu Dec 29 08:16:10 UTC 2016 : Endpoint response body before transformations: \"{\\\"cost\\\":\\\"1.23\\\",\\\"id\\\":\\\"1\\\",\\\"bookname\\\":\\\"test book\\\",\\\"isbn\\\":\\\"123\\\"}\"\nThu Dec 29 08:16:10 UTC 2016 : Endpoint response headers: {x-amzn-Remapped-Content-Length=0, x-amzn-RequestId=0b25323b-cd9f-11e6-8bd4-292925ba63a9, Connection=keep-alive, Content-Length=78, Date=Thu, 29 Dec 2016 08:16:10 GMT, Content-Type=application/json}\nThu Dec 29 08:16:10 UTC 2016 : Method response body after transformations: Empty\nThu Dec 29 08:16:10 UTC 2016 : Method response headers: {X-Amzn-Trace-Id=Root=1-5864c645-8494974a41a3a16c8d2f9929, Content-Type=application/json}\nThu Dec 29 08:16:10 UTC 2016 : Successfully completed execution\nThu Dec 29 08:16:10 UTC 2016 : Method completed with status: 200\n", 
    "latency": 5091, 
    "headers": {
        "X-Amzn-Trace-Id": "Root=1-5864c645-8494974a41a3a16c8d2f9929", 
        "Content-Type": "application/json"
    }
}

status属性的值为200,表示这是一次成功的调用。 log属性的值显示CloudWatch Logs中的日志语句。 还可以使用aws logs filter-log-events --log-group /aws/lambda/MicroservicePost获得详细日志。

  • 此命令在Couchbase中存储一个JSON文档。 可以使用Couchbase CLI工具cbq轻松地验证这一点。以以下方式连接到Couchbase服务器:
cbq -u Administrator -p password -e="http://<COUCHBASE_HOST>:8091"

default存储桶上创建一个主索引,因为这需要使用no子句查询存储桶:

cbq> create primary index default_index on default;
{
    "requestID": "13b539f9-7fff-4386-92f4-cea161a7aa08",
    "signature": null,
    "results": [
    ],
    "status": "success",
    "metrics": {
        "elapsedTime": "1.917009047s",
        "executionTime": "1.916970061s",
        "resultCount": 0,
        "resultSize": 0
    }
}
  • 编写N1QL查询以访问数据:
cbq> select * from default limit 10;
{
    "requestID": "d7b1c3f9-6b4e-4952-9a1e-9faf5169926e",
    "signature": {
        "*": "*"
    },
    "results": [
        {
            "default": {
                "bookname": "test",
                "cost": "1.23",
                "id": "1",
                "isbn": "123"
            }
        }
    ],
    "status": "success",
    "metrics": {
        "elapsedTime": "24.337755ms",
        "executionTime": "24.289796ms",
        "resultCount": 1,
        "resultSize": 175
    }
}

结果显示了由我们的Lambda函数存储的JSON文档。

API网关GET方法

让我们在资源上创建HTTP GET方法:

  • 创建一个GET方法:
--rest-api-id lb2qgujjif \
--resource-id vrpkod \
--http-method GET \
--authorization-type NONE
  • 将正确的Lambda函数设置为GET的目标:
aws apigateway put-integration \
--rest-api-id lb2qgujjif \
--resource-id vrpkod \
--http-method GET \
--type AWS \
--integration-http-method POST \
--uri arn:aws:apigateway:us-west-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-west-1:598307997273:function:MicroserviceGetAll/invocations
  • 设置GET方法响应的content-type
aws apigateway put-method-response \
--rest-api-id lb2qgujjif \
--resource-id vrpkod \
--http-method GET \
--status-code 200 \
--response-models "{\"application/json\": \"Empty\"}"
  • 设置GET方法集成响应的content-type
aws apigateway put-integration-response \
--rest-api-id lb2qgujjif \
--resource-id vrpkod \
--http-method GET \
--status-code 200 \
--response-templates "{\"application/json\": \"Empty\"}"
  • 授予权限以允许API网关调用Lambda函数
aws lambda add-permission \
--function-name MicroserviceGetAll \
--statement-id apigateway-test-getall-1 \
--action lambda:InvokeFunction \
--principal apigateway.amazonaws.com \
--source-arn "arn:aws:execute-api:us-west-1:598307997273:lb2qgujjif/*/GET/books"
  • 向部署的API授予权限:
aws lambda add-permission \
--function-name MicroserviceGetAll \
--statement-id apigateway-test-getall-2 \
--action lambda:InvokeFunction \
--principal apigateway.amazonaws.com \
--source-arn "arn:aws:execute-api:us-west-1:598307997273:lb2qgujjif/test/GET/books"
  • 测试方法:
aws apigateway test-invoke-method \
--rest-api-id lb2qgujjif \
--resource-id vrpkod \
--http-method GET

查看输出:

{
    "status": 200, 
    "body": "Empty", 
    "log": "Execution log for request test-request\nSat Dec 31 09:07:48 UTC 2016 : Starting execution for request: test-invoke-request\nSat Dec 31 09:07:48 UTC 2016 : HTTP Method: GET, Resource Path: /books\nSat Dec 31 09:07:48 UTC 2016 : Method request path: {}\nSat Dec 31 09:07:48 UTC 2016 : Method request query string: {}\nSat Dec 31 09:07:48 UTC 2016 : Method request headers: {}\nSat Dec 31 09:07:48 UTC 2016 : Method request body before transformations: \nSat Dec 31 09:07:48 UTC 2016 : Endpoint request URI: https://lambda.us-west-1.amazonaws.com/2015-03-31/functions/arn:aws:lambda:us-west-1:598307997273:function:MicroserviceGetAll/invocations\nSat Dec 31 09:07:48 UTC 2016 : Endpoint request headers: {x-amzn-lambda-integration-tag=test-request, Authorization=******************************************************************************************************************************************************************************************************************************************************************************************************6de147, X-Amz-Date=20161231T090748Z, x-amzn-apigateway-api-id=lb2qgujjif, X-Amz-Source-Arn=arn:aws:execute-api:us-west-1:598307997273:lb2qgujjif/null/GET/books, Accept=application/json, User-Agent=AmazonAPIGateway_lb2qgujjif, X-Amz-Security-Token=FQoDYXdzEHEaDEILpsKTo45Ys1LrFCK3A+KOe5HXOSP3GfVAaRYHe1pDUJGHL9MtkFiPjORLFT+UCKjRqE7UFaGscTVG6PZXTuSyQev4XTyROfPylCrtDomGsoZF/iwy4rlJQIJ7elBceyeKu1OVdaT1A99PVeliaCAiDL6Veo1viWOnP+7c72nAaJ5jnyF/nHl/OLhFdFv4t/hnx3JePMk5YM89/6ofxUEVDNfzXxbZHRpTrG/4TPHwjPdoR5i9dEzWMU6Eo5xD4ldQ/m5B3RmrwpaPOuEq39LhJ8k/Vzo+pAfgJTq5ssbNwYOgh0RPSGVNMcoTkCwk0EMMT5vDbmQqZ2dW1a1tmQg9N2xR+QQy+RKMFgO5YY8fMxHnRSdMuuipxl79G1pktc [TRUNCATED]\nSat Dec 31 09:07:48 UTC 2016 : Endpoint request body after transformations: \nSat Dec 31 09:07:53 UTC 2016 : Endpoint response body before transformations: \"[{\\\"default\\\":{\\\"cost\\\":\\\"1.23\\\",\\\"id\\\":\\\"1\\\",\\\"bookname\\\":\\\"test book\\\",\\\"isbn\\\":\\\"123\\\"}}]\"\nSat Dec 31 09:07:53 UTC 2016 : Endpoint response headers: {x-amzn-Remapped-Content-Length=0, x-amzn-RequestId=99ab09b2-cf38-11e6-996f-f5f07af431af, Connection=keep-alive, Content-Length=94, Date=Sat, 31 Dec 2016 09:07:52 GMT, Content-Type=application/json}\nSat Dec 31 09:07:53 UTC 2016 : Method response body after transformations: Empty\nSat Dec 31 09:07:53 UTC 2016 : Method response headers: {X-Amzn-Trace-Id=Root=1-58677564-66f1e96642b16d2db703126e, Content-Type=application/json}\nSat Dec 31 09:07:53 UTC 2016 : Successfully completed execution\nSat Dec 31 09:07:53 UTC 2016 : Method completed with status: 200\n", 
    "latency": 4744, 
    "headers": {
        "X-Amzn-Trace-Id": "Root=1-58677564-66f1e96642b16d2db703126e", 
        "Content-Type": "application/json"
    }
}

同样,200状态代码显示调用成功。 可以使用aws logs filter-log-events --log-group /aws/lambda/MicroservicePost获得详细的日志。

该博客仅显示了一种简单的POST和GET方法。 其他HTTP方法也可以很容易地包含在此微服务中。

API网关和Lambda参考

翻译自: https://www.javacodegeeks.com/2017/01/microservice-using-aws-api-gateway-aws-lambda-couchbase.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值