Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

API Gateway: missing features #723

Closed
5 of 12 tasks
eladb opened this issue Sep 17, 2018 · 23 comments · Fixed by #2960 or MechanicalRock/tech-radar#14 · May be fixed by MechanicalRock/cdk-constructs#5, MechanicalRock/cdk-constructs#6 or MechanicalRock/cdk-constructs#7
Closed
5 of 12 tasks
Assignees
Labels
@aws-cdk/aws-apigateway Related to Amazon API Gateway feature-request A feature should be added or improved. management/tracking Issues that track a subject or multiple issues

Comments

@eladb
Copy link
Contributor

eladb commented Sep 17, 2018

eladb pushed a commit that referenced this issue Sep 17, 2018
Introduce an initial construct library for API Gateway. By all means it does not cover 
the entire surface area of API Gateway, but provides basic support for defining 
API gateway configurations (resources/methods hierarchy).

Integration support includes `LambdaIntegration` which accepts a `lambda.Function`, 
sets up the appropriate permissions and binds it to an API method.

Includes many "smart defaults" at every level such as:

- Automatically define a `Deployment` and a `Stage` for the API, which will be recreated every time the API configuration changes (by generating the logical ID of the AWS::ApiGateway::Deployment resource from a hash of the API configuration, similarly to SAM).
- Automatically configure a role for API Gateway to allow writing CloudWatch logs and alarms.
- Specify `defaultIntegration` at the API level which will apply to all methods without integration.

Supports defining APIs like this:

```ts
const integ = new apigw.LambdaIntegration(toysLambdaHandler);
const api = new apigw.RestApi(this, 'my-awesome-api');

api.root.onMethod('GET', new apigw.HttpIntegration('https://amazon.com/toys'));

const toys = api.root.addResource('toys', { defaultIntegration: integ });
toys.addMethod('ANY');

const toy = toys.addResource('{toy}');
toy.addMethod('GET'); // get a toy
toy.addMethod('DELETE'); // remove a toy
```

See [README] for more details.

[README]: https://github.com/awslabs/aws-cdk/blob/c99e7285e7b24700cfd4d52f6da32cffe12c511c/packages/%40aws-cdk/aws-apigateway/README.md

### Framework Changes

 * __resolve__: allow object keys to include tokens, as long as they resolvable to strings.
 * __assert__: invoke `stack.validateTree()` by default for `expect(stack)` to simulate synthesis.

----

* Features not supported yet are listed here: #727, #723
* Fixes #602, copy: @hassankhan
@eladb eladb changed the title Missing features in API Gateway library API Gateway: missing features Sep 17, 2018
@rix0rrr rix0rrr added the feature-request A feature should be added or improved. label Nov 7, 2018
@debora-ito debora-ito added the @aws-cdk/aws-apigateway Related to Amazon API Gateway label Nov 7, 2018
@rix0rrr rix0rrr added the gap label Jan 4, 2019
@SpainTrain
Copy link

Looks like VPC Links were added in #1541 but perhaps there is more to that feature?

@dswhitener
Copy link

dswhitener commented Feb 13, 2019

Since the feature for MethodResponse is missing, Is there another way to add a method response to an API via .net core? I found this:

https://stackoverflow.com/questions/52752201/enabling-cors-for-aws-api-gateway-with-the-aws-cdk

but I'm not finding a way to translate that into .net core.. the closest i've gotten is this:

using AGW = Amazon.CDK.AWS.APIGateway;

//....jumping to the relevant part......

AGW.HttpIntegrationProps hip = new AGW.HttpIntegrationProps();
AGW.HttpIntegration awsHttpinteg = new AGW.HttpIntegration("http://some_api_here",hip);

AGW.CfnMethod.MethodResponseProperty mp = new AGW.CfnMethod.MethodResponseProperty();
var methd = api.Root.AddMethod("GET",awsHttpinteg,methOps);

var rps =new Dictionary<string, string>();
rps.Add("Access-Control-Allow-Origin", "'*'");
mp.ResponseParameters = rps;
mp.StatusCode = "200";

// now how do i attach that to the method? :(
// i.e. is there a workaround until the feature gets implemented?
// or do I have to go in manually and add it?

@dswhitener
Copy link

dswhitener commented Feb 20, 2019

For the record, I found this.. you can use the AWS cli to add a new method response,
https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-method-settings-method-response.html
for anyone stuck by the feature not being available in the CDK.
(so much easier to migrate when it's a reproducible command / code instead of directions for point-click in a UI)

@AlexRex
Copy link

AlexRex commented May 7, 2019

@dswhitener Did you find the solution for the CORS? I'm able to set the CORS for the OPTIONS method, but for instance if I want to add a GET method which integrates with a Lambda I'm not able to enable CORS.

@ranguard
Copy link
Contributor

Not sure everything was fixed with the PR :) ?

@orangewise
Copy link
Contributor

@ranguard Correct, only api keys and usage plans.

@AlexRex
Copy link

AlexRex commented May 30, 2019

What about domain names? Someone find out how to do it?

@abbottdev
Copy link

What about Swagger/Open API models?

@bgdnlp
Copy link

bgdnlp commented Jun 23, 2019

I know that this isn't a support forum, but this issue is one of the top results on Google. If it's inappropriate, please move it or let me know where to post.

For anyone who is looking to use the CDK, but got bitten by one of these missing features. There is an official way to work around these issues. Basically we can alter the CloudFormation resources directly. Similar concept to boto3 clients.

Here is an example of how to add an Authorizer in Python.

Assume we have an API Gateway and a POST a method:

api_gw = aws_apigateway.RestApi(self, 'MyApp')
post_method = api_gw.root.add_method(http_method='POST')

Set the authorizer using a low level CfnResource:

api_gw_authorizer = aws_apigateway.CfnAuthorizer(
    scope=self,
    id='my_authorizer',
    rest_api_id=api_gw.rest_api_id,
    name='MyAuth',
    type='COGNITO_USER_POOLS',
    identity_source='method.request.header.name.Authorization',
    provider_arns=[
        'arn:aws:cognito-idp:eu-west-1:123456789012:userpool/'
        'eu-west-1_MyCognito'])

Get the underlying CfnResource for the POST method created above:

post_method_resource = post_method.node.find_child('Resource')

Set the POST method to use the authorizer by adding the required CloudFormation properties to the low level resource:

post_method_resource.add_property_override('AuthorizationType',
                                           'COGNITO_USER_POOLS')
post_method_resource.add_property_override(
        'AuthorizerId',
        {"Ref": api_gw_authorizer.logical_id})

Take note of the second instruction, that's a dictionary. It needs to be, so that the AuthorizedId property is added correctly, like:

AuthorizerId:
  Ref: myauthorizer

instead of something like:

AuthorizerId: "Ref: myauthorizer"

As of 0.35.0, the above should output a template containing:

MyAppPOST853D1BB4:
  Type: AWS::ApiGateway::Method
  Properties:
    HttpMethod: POST
    ResourceId:
      Fn::GetAtt:
        - MyApp3CE31C26
        - RootResourceId
    RestApiId:
      Ref: MyApp3CE31C26
    AuthorizationType: COGNITO_USER_POOLS
    AuthorizerId:
      Ref: myauthorizer
    Integration:
      Type: MOCK
myauthorizer:
  Type: AWS::ApiGateway::Authorizer
  Properties:
    RestApiId:
      Ref: MyApp3CE31C26
    Type: COGNITO_USER_POOLS
    IdentitySource: method.request.header.name.Authorization
    Name: MyAuth
    ProviderARNs:
      - arn:aws:cognito-idp:eu-west-1:123456789012:userpool/eu-west-1_MyCognito

(removed Metadata for brevity)

@AlexRex
Copy link

AlexRex commented Jun 24, 2019

@bgdnlp well, actually it's even a bit easier as you don't need to override anything, at least in Typescript:

const apiGateway = new RestApi(this, 'apiGateway', {
  restApiName: `api name`
});

const apiGatewayRole = new Role(this, 'RestApiRole', {
  assumedBy: new ServicePrincipal('apigateway.amazonaws.com')
});


const authorizerUri = `arn:aws:apigateway:${this.props.region}:lambda:path/2015-03-31/functions/${
  this.authHandler.functionArn // lambda function of the authorizer
  }/invocations`;

const authorizer = new CfnAuthorizer(this, 'LambdaAuthorizer', {
  authorizerCredentials: apiGatewayRole.roleArn,
  authorizerUri,
  identitySource: 'method.request.header.Authorization',
  name: `rest-api-authorizer`,
  restApiId: apiGateway.restApiId,
  type: 'TOKEN',
  identityValidationExpression: 'Bearer (.*)',
  authorizerResultTtlInSeconds: 0
});


const userResource = apiGateway.root.addResource('user');

userResource
  .addMethod('POST', new LambdaIntegration(this.createUserHandler), {
    authorizationType: AuthorizationType.Custom,
    authorizerId: authorizer.authorizerId
  });

@bgdnlp
Copy link

bgdnlp commented Jun 24, 2019

That doesn't (shouldn't?) work any more in 0.35.0. Method's authorizerId property is gone, replaced with authorizer.

Edit: I can only speak for Python, but even if you try to set authorizer, it will not do anything, it will simply ignore it. In 0.35.0. The escape hatch works though.

Anyway, the authorizer is just an example. Your code works/worked for addMethod, but might not work for other methods. The override should work for all of them, as far as I understand.

@johncrn
Copy link
Contributor

johncrn commented Jun 25, 2019

Hi @bgdnlp ,
You're correct, even in typescript the authorizerId approach described above does not work in the 0.35.0 release.
I'm using typescript and have adopted the method you described in 0.35.0, works fine thanks for the tip.

@vlajos
Copy link

vlajos commented Jun 25, 2019

Re 0.35/typescript:
This one seems to be working (at least the stack has been created):

     authorizer: {
            authorizerId: authorizer.refAsString
     }

@vlajos
Copy link

vlajos commented Jun 26, 2019

And 0.36/typescript:

     authorizer: {
            authorizerId: authorizer.ref
     }

eladb pushed a commit that referenced this issue Jun 27, 2019
…d validators (#2960)

Fixes #905: "apigateway: "methodResponses" is missing from MethodOptions"
Fixes #1695: apigateway: missing support for models
Fixes #727: API Gateway: improve API for request parameters and responses
Fixes #723: API Gateway: missing features
Fixes #2957: RestApi to use logical id as a name for APIs instead of name of current construct
Adds support for JsonSchema in Model
Aligns Model to the PhysicalName convention.
No breaking change, documentation updated
@lapair
Copy link

lapair commented Jun 27, 2019

@eladb not everything done on this list please reopen (please also tick off those things that have been done as the list is getting much shorter!) - thank you :)

@eladb eladb reopened this Jun 27, 2019
@nija-at
Copy link
Contributor

nija-at commented Feb 12, 2020

For the remaining items on this list, I've opened and/or linked separate issues to track them

I'm closing this in favour of these smaller ones. With a large issue such as this, it's difficult to track everything that's going on in the comments, associate which features we're getting the 👍 reaction and estimate effort.

If you're interested or waiting for any of these, please +1 the individual issues one more time. Apologies for the churn.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment