Я боролся с этим в течение недели, и проблема связана с тем, как шлюз API построен из ресурсов и методов. Из документации
В Amazon API Gateway вы создаете REST API как набор программируемых объектов, известных как ресурсы API Gateway. Например, вы используете ресурс RestApi для представления API, который может содержать набор сущностей Resource. Каждая сущность Resource может, в свою очередь, иметь один или несколько ресурсов Method. Метод, выраженный в параметрах и теле запроса, определяет интерфейс прикладного программирования для доступа клиента к открытому ресурсу и представляет собой входящий запрос, отправленный клиентом.
Бессерверный интерфейс командной строки создает для вас все ресурсы/методы, когда у вас есть функция, запускаемая событием http.
functions:
GetScenesInGame:
handler: handler.hello
layers: arn:aws:lambda:eu-west-1:xxxxxxxxx:layer:pynamodb-layer:1
events:
- http:
method: GET
path: api/v1/game/{gameId}/scene
В приведенном выше примере создается пять ресурсов (api, v1, game, gameIdParam, scene) и, наконец, добавляется метод GET для конечного ресурса.
К сожалению, если у вас есть два отдельных стека (как это может быть в настройке микросервиса), если они являются какой-либо частью вышеуказанных методов, возникает ошибка Другой ресурс с тем же родителем уже имеет это имя.
Решение выделено в этой статье из бессерверного развертывания бессерверного микросервиса на aws, хотя это не очень ясно и легко пропустить.
Во-первых, есть шаблон облачного формирования верхнего уровня, который настраивает необходимые ресурсы.
Для ресурса, к которому вы хотите добавить бессерверную микрослужбу, вы экспортируете идентификатор ресурса в качестве выходной переменной в свой стек.
Затем в файле serverless.yml вы импортируете ссылку на шлюз API и идентификатор ресурса APIGateway.
Затем вы можете развернуть каждую службу без конфликта имен ресурсов в структуре API.
В приведенных ниже шаблонах показано наличие набора ресурсов верхнего уровня.
api/v1/game/{gameId}/page
api/v1/game/{gameId}/scene
Затем прикрепите PageService к ресурсу page и SceneService к ресурсу scene.
api-шлюз.yml
AWSTemplateFormatVersion: "2010-09-09"
Description: "S3 template for deploying S3 to be used by ACS s3 connector."
Resources:
TestApiGw:
Type: AWS::ApiGateway::RestApi
Properties:
Name: !Sub 'test-apigw-throwaway'
ApiResource:
Type: AWS::ApiGateway::Resource
Properties:
RestApiId: !Ref TestApiGw
ParentId: !GetAtt
- TestApiGw
- RootResourceId
PathPart: "api"
VersionResource:
Type: AWS::ApiGateway::Resource
Properties:
RestApiId: !Ref TestApiGw
ParentId: !Ref ApiResource
PathPart: "v1"
GameResource:
Type: AWS::ApiGateway::Resource
Properties:
RestApiId: !Ref TestApiGw
ParentId: !Ref VersionResource
PathPart: "game"
GameParamResource:
Type: AWS::ApiGateway::Resource
Properties:
RestApiId: !Ref TestApiGw
ParentId: !Ref GameResource
PathPart: "{gameId}"
SceneResource:
Type: AWS::ApiGateway::Resource
Properties:
RestApiId: !Ref TestApiGw
ParentId: !Ref GameParamResource
PathPart: "scene"
PageResource:
Type: AWS::ApiGateway::Resource
Properties:
RestApiId: !Ref TestApiGw
ParentId: !Ref GameParamResource
PathPart: "page"
Outputs:
ApiRestApiId:
Value: !Ref TestApiGw
Export:
Name: !Sub ${AWS::StackName}-TestApiId
ApiRootResourceId:
Value:
Fn::GetAtt:
- TestApiGw
- RootResourceId
Export:
Name: !Sub ${AWS::StackName}-ApiRootResourceVar
ApiSceneResourceVar:
Value: !Ref SceneResource
Export:
# variable names are global so this will need more work to make it unique across stages.
Name: !Sub ${AWS::StackName}-ApiSceneResourceVar
ApiPageResourceVar:
Value: !Ref PageResource
Export:
# variable names are global so this will need more work to make it unique across stages.
Name: !Sub ${AWS::StackName}-ApiPageResourceVar
serverless.yml (файл Serverless Cli для службы страниц)
service: scrap-page-service
provider:
name: aws
runtime: python2.7
apiGateway:
restApiId:
"Fn::ImportValue": throw-stack-1-TestApiId
restApiRootResourceId:
"Fn::ImportValue": throw-stack-1-ApiPageResourceVar
functions:
hello:
handler: handler.hello
events:
- http:
path: ""
method: get
serverless.yml (файл Serverless Cli для службы сцены)
service: scrap-scene-service
provider:
name: aws
runtime: python2.7
apiGateway:
restApiId:
"Fn::ImportValue": throw-stack-1-TestApiId
restApiRootResourceId:
"Fn::ImportValue": throw-stack-1-ApiSceneResourceVar
functions:
hello:
handler: handler.hello
events:
- http:
path: ""
method: get
Надеюсь, это поможет другим решить эту проблему, и если у кого-то есть лучший способ сделать это, мне было бы интересно узнать :-)
person
Alex Ward
schedule
15.11.2019