@@ -170,19 +170,32 @@ def __init__(
170170 path : str ,
171171 method_list : list [Method ],
172172 resource_list : list [Resource ] | None = None ,
173+ integration_uri : str | Ref | Sub | None = None ,
173174 lambda_arn : str | GetAtt | Ref | None = None ,
175+ lambda_arn_permission : str
176+ | GetAtt
177+ | Ref
178+ | dict [str , str | GetAtt | Ref ]
179+ | None = None ,
174180 ) -> None :
175181 """Initialize a REST API resource.
176182
177183 :param path: the last path segment for this resource
178184 :param method_list: a list of methods accepted on this resource
179185 :param resource_list: a list of child resources
186+ :param integration_uri: URI of a lambda function for this resource
180187 :param lambda_arn: arn of the lambda executed for this resource
188+ :param lambda_arn_permission: lambda arn for which to add InvokeFunction
189+ permission (can be different from the lambda arn executed
190+ by the REST API). A mapping from stage names to lambda arns can
191+ also be passed
181192 """
182193 self .path = path
183194 self .method_list = method_list
184195 self .resource_list = resource_list
196+ self .integration_uri = integration_uri
185197 self .lambda_arn = lambda_arn
198+ self .lambda_arn_permission = lambda_arn_permission
186199
187200
188201class Api (Construct ):
@@ -224,7 +237,6 @@ def __init__(
224237 :param hosted_zone_id: id of the hosted zone that contains domain_name.
225238 This parameter is required if domain_name is not None
226239 :param stages_config: configurations of the different stages
227- :param integration_uri: URI of a Lambda function
228240 """
229241 self .name = name
230242 self .description = description
@@ -895,35 +907,39 @@ def declare_stage(
895907 def _declare_method (
896908 self ,
897909 method : Method ,
898- resource : Resource ,
899910 resource_id_prefix : str ,
900911 resource_path : str ,
912+ resource_integration_uri : str | Ref | Sub | None = None ,
913+ resource_lambda_arn : str | GetAtt | Ref | None = None ,
914+ resource_lambda_arn_permission : str
915+ | GetAtt
916+ | Ref
917+ | dict [str , str | GetAtt | Ref ]
918+ | None = None ,
901919 ) -> list [AWSObject ]:
902920 """Declare a method.
903921
904922 :param method: the method definition
905- :param resource: resource associated with the method
906923 :param resource_id_prefix: resource_id without trailing Resource
907924 :param resource_path: absolute path to the resource
925+ :param resource_integration_uri: integration URI for the resource
926+ :param resource_lambda_arn: arn of lambda for the resource
927+ :param resource_lambda_arn_permission: lambda arn permission for the resource
908928 :return: a list of AWSObjects to be added to the stack
909929 """
910930 result = []
911931 id_prefix = name_to_id (f"{ resource_id_prefix } -{ method .method } " )
912932
913- # Take the global lambda_arn or the one configured for the resource
914- lambda_arn = (
915- self .lambda_arn if resource .lambda_arn is None else resource .lambda_arn
916- )
917-
918- # Integration URI for the resource
933+ # Take the global integration uri or the one configured for the resource
919934 integration_uri = (
920935 self .integration_uri
921- if self .integration_uri is not None
922- else Sub (
923- "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31"
924- "/functions/${lambdaArn}/invocations" ,
925- dict_values = {"lambdaArn" : lambda_arn },
926- )
936+ if resource_integration_uri is None
937+ else resource_integration_uri
938+ )
939+
940+ # Take the global lambda arn or the one configured for the resource
941+ lambda_arn = (
942+ self .lambda_arn if resource_lambda_arn is None else resource_lambda_arn
927943 )
928944
929945 integration = apigateway .Integration (
@@ -934,7 +950,13 @@ def _declare_method(
934950 IntegrationHttpMethod = "POST" ,
935951 PassthroughBehavior = "NEVER" ,
936952 Type = "AWS_PROXY" ,
937- Uri = integration_uri ,
953+ Uri = integration_uri
954+ if integration_uri is not None
955+ else Sub (
956+ "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31"
957+ "/functions/${lambdaArn}/invocations" ,
958+ dict_values = {"lambdaArn" : lambda_arn },
959+ ),
938960 )
939961
940962 method_params = {
@@ -952,6 +974,16 @@ def _declare_method(
952974 result .append (apigateway .Method (f"{ id_prefix } Method" , ** method_params ))
953975
954976 for config in self .stages_config :
977+ if resource_lambda_arn_permission is not None :
978+ # Use the lambda_arn_permission configured for resource
979+ if isinstance (resource_lambda_arn_permission , dict ):
980+ assert (
981+ config .name in resource_lambda_arn_permission
982+ ), f"missing lambda arn permission for stage { config .name } "
983+ lambda_arn = resource_lambda_arn_permission [config .name ]
984+ else :
985+ lambda_arn = resource_lambda_arn_permission
986+
955987 result .append (
956988 awslambda .Permission (
957989 name_to_id (f"{ id_prefix } -{ config .name } LambdaPermission" ),
@@ -1019,13 +1051,25 @@ def _declare_resources(
10191051 resource_list : list [Resource ],
10201052 parent_id_prefix : str | None = None ,
10211053 parent_path : str | None = None ,
1054+ parent_integration_uri : str | Ref | Sub | None = None ,
1055+ parent_lambda_arn : str | GetAtt | Ref | None = None ,
1056+ parent_lambda_arn_permission : str
1057+ | GetAtt
1058+ | Ref
1059+ | dict [str , str | GetAtt | Ref ]
1060+ | None = None ,
10221061 ) -> list [AWSObject ]:
10231062 """Create API resources and methods recursively.
10241063
10251064 Each resource can define its own methods and have child resources.
10261065
10271066 :param resource_list: list of resources
10281067 :param parent_id_prefix: id of the parent resource without trailing Resource
1068+ :param parent_path: absolute path to the parent resource
1069+ :param parent_integration_uri: integration URI of the parent resource
1070+ :param parent_lambda_arn: lambda arn of the parent resource
1071+ :param parent_lambda_arn_permission: lambda arn permission of the
1072+ parent resource
10291073 :return: a list of AWSObjects to be added to the stack
10301074 """
10311075 result : list [AWSObject ] = []
@@ -1059,13 +1103,36 @@ def _declare_resources(
10591103
10601104 result .append (resource )
10611105
1106+ # Get the integration URI of this resource.
1107+ # It must be forwarded to children so that they recursively use the
1108+ # same URI
1109+ resource_integration_uri = (
1110+ r .integration_uri
1111+ if r .integration_uri is not None
1112+ else parent_integration_uri
1113+ )
1114+
1115+ # Same for the lambda arn
1116+ resource_lambda_arn = (
1117+ r .lambda_arn if r .lambda_arn is not None else parent_lambda_arn
1118+ )
1119+
1120+ # Same fo the lambda arn permission
1121+ resource_lambda_arn_permission = (
1122+ r .lambda_arn_permission
1123+ if r .lambda_arn_permission is not None
1124+ else parent_lambda_arn_permission
1125+ )
1126+
10621127 # Declare the methods of this resource
10631128 for method in r .method_list :
10641129 result += self ._declare_method (
10651130 method = method ,
1066- resource = r ,
10671131 resource_id_prefix = resource_id_prefix ,
10681132 resource_path = resource_path ,
1133+ resource_integration_uri = resource_integration_uri ,
1134+ resource_lambda_arn = resource_lambda_arn ,
1135+ resource_lambda_arn_permission = resource_lambda_arn_permission ,
10691136 )
10701137
10711138 # Declare the children of this resource
@@ -1074,6 +1141,9 @@ def _declare_resources(
10741141 resource_list = r .resource_list ,
10751142 parent_id_prefix = resource_id_prefix ,
10761143 parent_path = resource_path ,
1144+ parent_integration_uri = resource_integration_uri ,
1145+ parent_lambda_arn = resource_lambda_arn ,
1146+ parent_lambda_arn_permission = resource_lambda_arn_permission ,
10771147 )
10781148
10791149 return result
0 commit comments