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

feat(aws-apigatewayv2): l2 construct for api gateway v2 #7097

Closed
wants to merge 24 commits into from
Closed

feat(aws-apigatewayv2): l2 construct for api gateway v2 #7097

wants to merge 24 commits into from

Conversation

julienlepine
Copy link
Contributor

Initial implementation of the API Gateway V2 Constructs.
Implements all base APIGW constructs as L2 Constructs.

fixes #5301
fixes #2872
fixes #212

Initial implementation of the API Gateway V2 Constructs.
Implements all base APIGW constructs as L2 Constructs.

fixes #5301
fixes #2872
fixes #212
Merge from remote master
@julienlepine
Copy link
Contributor Author

@nija-at I finally found the time to tidy up my initial hacky API Gateway v2 L2 construct, happy to review.

Copy link

@adamnfish adamnfish left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm really excited to see this come to CDK. I noticed a couple of things in the README but I'm only looking at this from the perspective of a potential user.

Thanks heaps for the hard work involved in getting this PR up.


```ts
const api = new apigatewayv2.Api(this, 'books-api', {
protocolType: apigatewayv2.ProtocolType.HTTP

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on the preceding paragraph, should this be using the apigatewayv2.ProtocolType.WEBSOCKET protocol?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like the same may be true of a few other examples here - the code snippet doesn't match up to the description?

@ranman
Copy link

ranman commented Apr 9, 2020

I'm also excited to see this soon. Is there anything I can help with?

Comment on lines 342 to 374
switch (props.protocolType) {
case ProtocolType.WEBSOCKET: {
if (props.basePath !== undefined) {
throw new Error('"basePath" is only supported with HTTP APIs');
}
if (props.body !== undefined) {
throw new Error('"body" is only supported with HTTP APIs');
}
if (props.bodyS3Location !== undefined) {
throw new Error('"bodyS3Location" is only supported with HTTP APIs');
}
if (props.corsConfiguration !== undefined) {
throw new Error('"corsConfiguration" is only supported with HTTP APIs');
}
if (props.routeSelectionExpression === undefined) {
throw new Error('"routeSelectionExpression" is required for Web Socket APIs');
}
break;
}
case ProtocolType.HTTP:
case undefined: {
if (props.apiKeySelectionExpression !== undefined) {
throw new Error('"apiKeySelectionExpression" is only supported with Web Socket APIs');
}
if (props.disableSchemaValidation !== undefined) {
throw new Error('"disableSchemaValidation" is only supported with Web Socket APIs');
}
if (props.routeSelectionExpression !== undefined && props.apiKeySelectionExpression !== KnownRouteSelectionExpression.METHOD_PATH) {
throw new Error('"routeSelectionExpression" has a single supported value for HTTP APIs: "${request.method} ${request.path}"');
}
break;
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because of the level of differences between HTTP and Websocket APIs, I'm wondering if it would be cleaner to split these up into separate L2s.

A customer is going to know right from the beginning if they're building an HTTP API or a Websocket API.
It seems to me that we could provide a richer experience if we define two separate L2s for these.
I don't think it's possible or makes sense to mix routes between them, does it?

Another example is routes.
Routes in websocket are fairly different from routes in HTTP API. They can both be modeled as a string, but there may be value in modeling them even more strongly in the CDK.

With integrations, while both websocket and HTTP support Lambda and HTTP integrations, websocket also supports AWS service integrations but the HTTP API supports private integrations.

And so it goes on...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have another open PR for APIGWv2 support. Take a look at some API suggestions on how this could look instead - #6432 (comment).

Let me know what you think.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a potential consumer of this I don't care if it is exposed via 2 different L2 APIs as long as I can use the functionality of both and get compile time errors if I have a mismatch between configurations and usage. If two different L2 APIs make that easier then I say go for it!

Really hoping to see this feature soon as the v2 APIGW APIs have some great features I want to use!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i really like @pahud 's view, will use his view and combine with this PR

Support ESLint rules:
- [comma-dangle]: Missing trailing comma
- [quotes]: Strings must use singlequote'
@nija-at
Copy link
Contributor

nija-at commented Apr 28, 2020

@julienlepine - I'm working with @pahud's this week on his PR to try and get a minimum set of CDK code for APIGWv2, with the aim to iron out an ergonomic API.
Letting you know in case you want to wait to see how that pans out.

@julienlepine
Copy link
Contributor Author

julienlepine commented Apr 28, 2020 via email

@julienlepine
Copy link
Contributor Author

Pushed, checked with @nija-at he will look at it.

Copy link
Contributor

@nija-at nija-at left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The awesome thing about this PR is that it has implemented a significant number of APIGWv2 features, if not all. This is a great job @julienlepine! 😊

However, I feel that this is missing a few patterns to get to a CDK module - this is mainly around using union types and how we have layered Http and Websocket on top of Api. (see individual comments below)

Over the next few days I'm going to try and re-hash either this or the other PR to get the right ergonomic pattern, but with only a very minimal set of features.
Once we get the right pattern going, features here can be re-based onto it piecemeal.

This would be a good way to divide and conquer here.

*/
public addRoute(
key: HttpRouteName,
integration: Integration | LambdaIntegration | HttpIntegration | ServiceIntegration,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, we don't support union types in the CDK yet, so this is not going to work. Union types translate into Object in Java and C#.

You will have to use the bind integration pattern.

The best example for this is how we've done event sources in the lambda package. See https://github.com/aws/aws-cdk/blob/master/packages/%40aws-cdk/aws-lambda/lib/event-source.ts and https://github.com/aws/aws-cdk/tree/master/packages/%40aws-cdk/aws-lambda-event-sources/lib.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This applies in all other places you've done union types.

Comment on lines 206 to 224
/**
* The OpenAPI definition.
*
* To import an HTTP API, you must specify `body` or `bodyS3Location`.
*
* Supported only for HTTP APIs.
* @default - `bodyS3Location` if defined, or no import
*/
readonly body?: string;

/**
* The S3 location of an OpenAPI definition.
*
* To import an HTTP API, you must specify `body` or `bodyS3Location`.
*
* Supported only for HTTP APIs.
* @default - `body` if defined, or no import
*/
readonly bodyS3Location?: BodyS3Location;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would drop these entirely for now. Let's add support for this in a separate PR.
They need to be modeled differently in the L2s. See #7372

/**
* Available protocols for ApiGateway V2 APIs (currently only 'WEBSOCKET' is supported)
*/
export enum ProtocolType {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would change this to be a class instead, so as to support protocol types not yet supported by the cdk.

See https://github.com/aws/aws-cdk/blob/master/packages/@aws-cdk/aws-lambda/lib/runtime.ts#L25

* By default, the API will automatically be deployed and accessible from a
* public endpoint.
*/
export class Api extends Resource implements IApi {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't quite see much value in having Api. It feels like it's just L1 + validation, and this validation is what CF already provides.

Copy link
Contributor

@nija-at nija-at left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@julienlepine - we now have a structure of the APIGatewayV2 package with the patterns well organized - https://github.com/aws/aws-cdk/tree/master/packages/%40aws-cdk/aws-apigatewayv2.

It currently only has HTTP APIs but I hope it's clear on where the websocket APIs will go under.
I recommend following this same pattern and contribute on top of this change.

I would also highly appreciate it if we could features piecemeal in smaller PRs than one massive PR. This makes it much easier on the reviewer and yourself to iterate and add small changes in.

Merged the model to be compatible with the new Http Api Model
…es) to classes

Update of the classes of API Gateway V2 to use classes instead of enums for open-ended value lists (known content type, routes, models, ...)
…rations

Bind the IAM policies for Lambda functions ro the integration/route pair, instead of just to the API/Integration pair.
@mergify mergify bot dismissed nija-at’s stale review July 1, 2020 09:33

Pull request has been modified.

@nija-at
Copy link
Contributor

nija-at commented Jul 2, 2020

I would also highly appreciate it if we could features piecemeal in smaller PRs than one massive PR. This makes it much easier on the reviewer and yourself to iterate and add small changes in.

Hey @julienlepine - As mentioned, can we break this up into reviewable chunks? Each chunk focused on adding a specific feature, starting from the most basic set of code needed to create a super simple Websocket endpoint, and then building up from there, one feature at a time.

nija-at
nija-at previously requested changes Jul 8, 2020
Copy link
Contributor

@nija-at nija-at left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moving to request changes. See #7097 (comment)

@mergify mergify bot dismissed nija-at’s stale review August 27, 2020 08:18

Pull request has been modified.

@aws-cdk-automation
Copy link
Collaborator

AWS CodeBuild CI Report

  • CodeBuild project: AutoBuildProject6AEA49D1-qxepHUsryhcu
  • Commit ID: d6dcb02
  • Result: FAILED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

@adamdottv
Copy link
Contributor

@nija-at @julienlepine is this still being worked on? If not, I'd like to add an L2 for WebSocket APIs if all parties are 👌 with that!

@nija-at
Copy link
Contributor

nija-at commented Sep 1, 2020

@adamelmore - feel free to contribute here.

We have limited amount of people and time to review external contributions, so keeping PRs small and easy to review will be highly appreciated. Unfortunately, large PRs are hard to review and unlikely to get completed.

I would begin by picking the simplest use case of building constructs that allow creating a very basic websocket endpoint with little configurability. That will set up the structure of the code, and subsequent PRs can make the feature set richer.

As an example, this is the approach we've been taking for HTTP APIs - https://github.com/aws/aws-cdk/commits/7b297749bbe5d75f29f1aeb2652d095e3f2630e1/packages/%40aws-cdk/aws-apigatewayv2/lib

@nija-at
Copy link
Contributor

nija-at commented Sep 2, 2020

I'm closing this PR for the time being. Feel free to reopen when it's ready with the changes - #7097 (review)

It may also makes sense to open a separate PR when this is broken up into smaller, reviewable chunks.

@nija-at nija-at closed this Sep 2, 2020
@julienlepine
Copy link
Contributor Author

julienlepine commented Sep 2, 2020 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
6 participants