1

我使用 mongoDb 和 nodeJs 创建了一个简单的 crud API lambda,它运行良好。所以我转到另一个步骤,我目前正在使用 yaml 文件中的开放 api 规范创建一个带有 terraform 的 AWS API 网关。这是我的招摇文件:

info:
  description: "API Ankan-v2"
  version: "V0.0.1"
  title: "ANKAN V2 API"
host: "localhost:4567"
basePath: "/restapis/api/{apiId}/test/_user_request_"
tags:
  - name: "user"
    description: "Operations about user"
schemes:
  - "http"
#    - "https"
paths:
  /documents/{documentId}:
    get:
      tags:
        - "document"
      summary: "Find document by ID"
      description: "Returns a single document"
      operationId: "readOneDocument"
      produces:
        - "application/json"
      parameters:
        - name: "documentId"
          in: "path"
          description: "Id of document"
          required: true
          type: "string"
      responses:
        200:
          description: "successful operation"
          schema:
            $ref: "#/definitions/Document"
        404:
          description: "document not found"
      x-amazon-apigateway-integration:
        uri: ${get_lambda_arn}
        passthroughBehavior: "WHEN_NO_MATCH"
        httpMethod: "POST"
        type: "AWS_PROXY"
    options:
      consumes:
        - "application/json"
      produces:
        - "application/json"
      parameters:
        - name: "documentId"
          in: "path"
          description: "Id of document"
          required: true
          type: "string"
      responses:
        200:
          description: "200 response"
          schema:
            $ref: "#/definitions/Document"
      x-amazon-apigateway-integration:
        responses:
          default:
            statusCode: "200"
            responseParameters:
              method.response.header.Access-Control-Allow-Methods: "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'"
              method.response.header.Access-Control-Allow-Headers: "'Content-Type,Authorization,X-Amz-Date,X-Api-Key,X-Amz-Security-Token'"
              method.response.header.Access-Control-Allow-Origin: "'*'"
        requestTemplates:
          application/json: "{\"statusCode\": 200}"
        passthroughBehavior: "when_no_match"
        type: "mock"
    x-amazon-apigateway-any-method:
      produces:
        - "application/json"
      parameters:
        - name: "documentId"
          in: "path"
          description: "Id of document"
          required: true
          type: "string"
      responses: {}
      x-amazon-apigateway-integration:
        responses:
          default:
            statusCode: "200"
        uri: ${get_lambda_arn}
        passthroughBehavior: "WHEN_NO_MATCH"
        httpMethod: "POST"
        cacheNamespace: "1rnijn"
        cacheKeyParameters:
          - "method.request.path.documentId"
        type: "AWS"
definitions:
  Document:
    type: "object"
    required:
      - "documentName"
      - "documentPath"
      - "miniature"
      - "status"
      - "date"
    properties:
      _id:
        type: "string"
        readOnly: true
      documentName:
        type: "string"
      documentPath:
        type: "string"
      miniature:
        type: "string"
      status:
        type: "string"
        enum:
          - "VALID"
          - "ERROR"
          - "ONLOAD"
      date:
        type: "string"
        format: "date"
    xml:
      name: "Document" 

在我的 terraform 中,我删除了集成和方法,因为我在我的招摇中添加了它们。所以我需要在 aws_api_gateway_rest_api 中导入 swagger 文件body = data.template_file.swagger.rendered

resource "aws_api_gateway_rest_api" "api" {
  name = "api-gateway"
  description = "document api"
  body = data.template_file.swagger.rendered

}


data "template_file" "swagger" {
  template = jsonencode("${path.module}/../../../../shared/swagger.yaml")

  vars = {
    get_lambda_arn = local.get_lambda_arn
  }
}
output "json" {
  value = data.template_file.swagger.rendered
}

locals {
  get_lambda_arn = aws_lambda_function.lambda_document.invoke_arn
}

resource "aws_api_gateway_resource" "documents" {
  rest_api_id = aws_api_gateway_rest_api.api.id
  parent_id   = aws_api_gateway_rest_api.api.root_resource_id
  path_part   = "documents"
  depends_on  = [aws_api_gateway_rest_api.api]
}

resource "aws_api_gateway_resource" "document_by_id" {
  parent_id   = aws_api_gateway_resource.documents.id
  path_part   = "{documentId}"
  rest_api_id = aws_api_gateway_rest_api.api.id
}


resource "aws_api_gateway_deployment" "ApiDeloyment" {
  rest_api_id = aws_api_gateway_rest_api.api.id
  stage_name = "INT"

  depends_on = [aws_api_gateway_rest_api.api]
}


resource "aws_lambda_function" "lambda_document" {
  function_name = "lambda_document"
  handler = "lambda.handler"
  role = "arn:aws::iam::123456:role/irrelevant"
  runtime = "nodejs10.x"
  filename = "${path.module}/lambda.zip"

  source_code_hash = filebase64sha256("${path.module}/lambda.zip")
}

应用 terraform 后,我在 terraform 日志中收到此消息

terraform apply --auto-approve
module.backend_api.module.document.aws_api_gateway_rest_api.api: Creating...
module.backend_api.module.document.aws_lambda_function.lambda_document: Creating...
module.backend_api.module.document.aws_lambda_function.lambda_document: Creation complete after 5s [id=lambda_document]
module.backend_api.module.document.data.template_file.swagger: Refreshing state...
module.backend_api.module.document.aws_api_gateway_rest_api.api: Still creating... [10s elapsed]
module.backend_api.module.document.aws_api_gateway_rest_api.api: Still creating... [20s elapsed]
module.backend_api.module.document.aws_api_gateway_rest_api.api: Still creating... [30s elapsed]
module.backend_api.module.document.aws_api_gateway_rest_api.api: Still creating... [40s elapsed]
module.backend_api.module.document.aws_api_gateway_rest_api.api: Still creating... [50s elapsed]
module.backend_api.module.document.aws_api_gateway_rest_api.api: Still creating... [1m0s elapsed]
module.backend_api.module.document.aws_api_gateway_rest_api.api: Still creating... [1m10s elapsed]

我的 docker-compose 日志显示了这一点

localstack        | 2020-01-13T07:37:56:ERROR:localstack.services.generic_proxy: Error forwarding request: Expecting value: line 1 column 1 (char 0) Traceback (most recent call last):
localstack        |   File "/opt/code/localstack/localstack/services/generic_proxy.py", line 242, in forward
localstack        |     path=path, data=data, headers=forward_headers)
localstack        |   File "/opt/code/localstack/localstack/services/apigateway/apigateway_listener.py", line 53, in forward_request
localstack        |     data = data and json.loads(to_str(data))
localstack        |   File "/usr/lib/python3.7/json/__init__.py", line 348, in loads
localstack        |     return _default_decoder.decode(s)
localstack        |   File "/usr/lib/python3.7/json/decoder.py", line 337, in decode
localstack        |     obj, end = self.raw_decode(s, idx=_w(s, 0).end())
localstack        |   File "/usr/lib/python3.7/json/decoder.py", line 355, in raw_decode
localstack        |     raise JSONDecodeError("Expecting value", s, err.value) from None
localstack        | json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

PS:我尝试使用 JSON 但同样的问题

有什么解决办法吗?我想在 localstack 中使用 terraform 将 swagger 与 api 网关集成

4

1 回答 1

1

这是 moto 库的问题。在后台,本地堆栈使用 moto 创建其资源,包括模拟 api 网关。不幸的是,moto 目前不支持将 swagger 文件定义作为 api 网关部署的一部分的 body 参数。因此,即使您提供有效的 swagger 文件和 api 网关配置(即在 aws 中工作的配置),localstack 也无法构建它。

于 2020-05-05T05:32:29.573 回答