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

BREAKING: Introduce an interface for DynamoDB attribute #720

Merged
merged 1 commit into from
Sep 18, 2018
Merged

BREAKING: Introduce an interface for DynamoDB attribute #720

merged 1 commit into from
Sep 18, 2018

Conversation

jungseoklee
Copy link
Contributor

@jungseoklee jungseoklee commented Sep 16, 2018

Changes since v1:

  • Redesign signature of add{Partition|Sort}Key methods which is a breaking change
  • Rename AttributeProps to Attribute
  • Rename KeyAttributeType to AttributeType

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license.

Summary

This patch introduces AttributeProps to represent DynamoDB attribute and deprecates add{Partition|Sort}Key(name, type) methods.

Why AttributeProps needed?

It is needed to represent the fact that both name and type are required when defining attributes for table and global or local secondary indexes. Whereas DynamoDB CloudFormation abstracts it through AttributeDefinition, CDK does not have a corresponding concept yet, which makes supporting GSI and LSI complicated and cumbersome.

Here is an example designing a GSI property. We can deal with partition and sort keys without an additional property. It is not concise though. How about handling NonKeyAttributes? NonKeyAttributes should be part of AttributeDefinitions, which means the GSI property should know their types as well. AttributeProps simplifies this matter.

// with AttributeProps
export interface GlobalSecondaryIndexProps {
    indexName: string;

    partitionKey: AttributeProps;

    sortKey?: AttributeProps;

    projectionType: ProjectionType;

    nonKeyAttributes?: AttributeProps[];

    readCapacity?: number;

    writeCapacity?: number;
}

// without AttributeProps
export interface GlobalSecondaryIndexProps {
    indexName: string;

    partitionKeyName: string;

    partitionKeyType: KeyAttributeType;  

    sortKeyName?: string;

    sortKeyType?: KeyAttributeType;

    projectionType: ProjectionType;

    nonKeyAttributes?: ???;

    readCapacity?: number;

    writeCapacity?: number;
}

Why add{Partition|Sort}Key(name, type) deprecated?

IMHO, it does not align with a way to define database schema. Both name and type always come together when defining partition and sort keys. In that sense, it would be natural to group them.

Test

OK: 33 assertions (287ms)

=============================== Coverage summary ===============================
Statements   : 97.5% ( 78/80 )
Branches     : 91.84% ( 45/49 )
Functions    : 100% ( 18/18 )
Lines        : 97.4% ( 75/77 )
================================================================================
Verifying integ.dynamodb.js against integ.dynamodb.expected.json... OK.

Copy link
Contributor

@rix0rrr rix0rrr left a comment

Choose a reason for hiding this comment

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

I agree with the gist of this change, but there are some (naming) modifications I'd like to see done to the current proposal.

/**
* @deprecated Use addPartitionKey(props: AttributeProps) instead.
*/
public addPartitionKey(name: string, type: KeyAttributeType): this;
Copy link
Contributor

Choose a reason for hiding this comment

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

No overloads please (does not translate to every jsii language).

Now is the time to break this API, if we're going to do so.

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 do not have a clear picture on backward compatibility rules. That is why I overloaded the method.

I would prefer breaking it if this is allowed. If this PR is a right direction to support GSI and LSI, the indexes will give users different API experience when defining partition and sort keys. It means that we will have API inconsistency which is not ideal.

Copy link
Contributor

Choose a reason for hiding this comment

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

We are pre-1.0, feel free to break. Just make sure you follow conventional-commits to indicate the break

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for comments! I will prepare the next revision.

@@ -66,6 +66,18 @@ export interface TableProps {
writeAutoScaling?: AutoScalingProps;
}

export interface AttributeProps {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this might better be called Attribute. Props is usually reserved for the set of parameters we use to instantiate a new class, which this is not.

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 will rename it in the next revision.

/**
* The data type of an attribute.
*/
type: KeyAttributeType;
Copy link
Contributor

Choose a reason for hiding this comment

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

Does it make sense for this type to still be called KeyAttributeType, since you're proposing to use Attribute also for things like nonKeyAttributes? Should it not be called AttributeType instead?

On an unrelated note: does it make sense to default it to AttributeType.String?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Does it make sense for this type to still be called KeyAttributeType, since you're proposing to use Attribute also for things like nonKeyAttributes?

You're right. AttributeType is an appropriate name here.

On an unrelated note: does it make sense to default it to AttributeType.String?

That makes sense for partition key in most cases, but sort key is a bit different. AttributeType.Number is also widely used for query efficiency.

This patch introduces an interface to represent DynamoDB attribute
and changes signature of add{Partition|SortKey} methods.
@jungseoklee jungseoklee changed the title Introduce AttributeProps to represent DynamoDB attribute BREAKING: Introduce an interface for DynamoDB attribute Sep 18, 2018
@rix0rrr rix0rrr merged commit e6cc189 into aws:master Sep 18, 2018
eladb pushed a commit that referenced this pull request Sep 20, 2018
__NOTICE__: This release includes a framework-wide [__breaking
change__](#712) which changes the type
of all the string resource attributes across the framework. Instead of using
strong-types that extend `cdk.Token` (such as `QueueArn`, `TopicName`, etc), we
now represent all these attributes as normal `string`s, and codify the tokens
into the string (using the feature introduced in [#168](#168)).

Furthermore, the `cdk.Arn` type has been removed. In order to format/parse ARNs,
use the static methods on `cdk.ArnUtils`.

See motivation and discussion in [#695](#695).

* **cfn2ts:** use stringified tokens for resource attributes instead of strong types ([#712](#712)) ([6508f78](6508f78)), closes [#518](#518) [#695](#695) [#744](#744)
* **aws-dynamodb:** Attribute type for keys, changes the signature of the `addPartitionKey` and `addSortKey` methods to be consistent across the board. ([#720](#720)) ([e6cc189](e6cc189))
* **aws-codebuild:** fix typo "priviledged" -> "privileged

* **assets:** cab't use multiple assets in the same stack ([#725](#725)) ([bba2e5b](bba2e5b)), closes [#706](#706)
* **aws-codebuild:** typo in BuildEnvironment "priviledged" -> "privileged     ([#734](#734)) ([72fec36](72fec36))
* **aws-ecr:** fix addToResourcePolicy ([#737](#737)) ([eadbda5](eadbda5))
* **aws-events:** ruleName can now be specified ([#726](#726)) ([a7bc5ee](a7bc5ee)), closes [#708](#708)
* **aws-lambda:** jsii use no long requires 'sourceAccount' ([#728](#728)) ([9e7d311](9e7d311)), closes [#714](#714)
* **aws-s3:** remove `policy` argument ([#730](#730)) ([a79190c](a79190c)), closes [#672](#672)
* **cdk:** "cdk init" java template is broken ([#732](#732)) ([281c083](281c083)), closes [#711](#711) [aws/jsii#233](aws/jsii#233)

* **aws-apigateway:** new API Gateway Construct Library ([#665](#665)) ([b0f3857](b0f3857))
* **aws-cdk:** detect presence of EC2 credentials ([#724](#724)) ([8e8c295](8e8c295)), closes [#702](#702) [#130](#130)
* **aws-codepipeline:** make the Stage insertion API in CodePipeline more flexible ([#460](#460)) ([d182818](d182818))
* **aws-codepipeline:** new "Pipeline#addStage" convenience method ([#647](#647)) ([25c9fa0](25c9fa0))
* **aws-rds:** add support for parameter groups ([#729](#729)) ([2541508](2541508)), closes [#719](#719)
* **docs:** add documentation for CDK toolkit plugings ([#733](#733)) ([965b918](965b918))
* **dependencies:** upgrade to [jsii 0.7.6](https://github.com/awslabs/jsii/releases/tag/v0.7.6)
eladb pushed a commit that referenced this pull request Sep 20, 2018
* v0.9.2

__NOTICE__: This release includes a framework-wide [__breaking
change__](#712) which changes the type
of all the string resource attributes across the framework. Instead of using
strong-types that extend `cdk.Token` (such as `QueueArn`, `TopicName`, etc), we
now represent all these attributes as normal `string`s, and codify the tokens
into the string (using the feature introduced in [#168](#168)).

Furthermore, the `cdk.Arn` type has been removed. In order to format/parse ARNs,
use the static methods on `cdk.ArnUtils`.

See motivation and discussion in [#695](#695).

* **cfn2ts:** use stringified tokens for resource attributes instead of strong types ([#712](#712)) ([6508f78](6508f78)), closes [#518](#518) [#695](#695) [#744](#744)
* **aws-dynamodb:** Attribute type for keys, changes the signature of the `addPartitionKey` and `addSortKey` methods to be consistent across the board. ([#720](#720)) ([e6cc189](e6cc189))
* **aws-codebuild:** fix typo "priviledged" -> "privileged

* **assets:** cab't use multiple assets in the same stack ([#725](#725)) ([bba2e5b](bba2e5b)), closes [#706](#706)
* **aws-codebuild:** typo in BuildEnvironment "priviledged" -> "privileged     ([#734](#734)) ([72fec36](72fec36))
* **aws-ecr:** fix addToResourcePolicy ([#737](#737)) ([eadbda5](eadbda5))
* **aws-events:** ruleName can now be specified ([#726](#726)) ([a7bc5ee](a7bc5ee)), closes [#708](#708)
* **aws-lambda:** jsii use no long requires 'sourceAccount' ([#728](#728)) ([9e7d311](9e7d311)), closes [#714](#714)
* **aws-s3:** remove `policy` argument ([#730](#730)) ([a79190c](a79190c)), closes [#672](#672)
* **cdk:** "cdk init" java template is broken ([#732](#732)) ([281c083](281c083)), closes [#711](#711) [aws/jsii#233](aws/jsii#233)

* **aws-apigateway:** new API Gateway Construct Library ([#665](#665)) ([b0f3857](b0f3857))
* **aws-cdk:** detect presence of EC2 credentials ([#724](#724)) ([8e8c295](8e8c295)), closes [#702](#702) [#130](#130)
* **aws-codepipeline:** make the Stage insertion API in CodePipeline more flexible ([#460](#460)) ([d182818](d182818))
* **aws-codepipeline:** new "Pipeline#addStage" convenience method ([#647](#647)) ([25c9fa0](25c9fa0))
* **aws-rds:** add support for parameter groups ([#729](#729)) ([2541508](2541508)), closes [#719](#719)
* **docs:** add documentation for CDK toolkit plugings ([#733](#733)) ([965b918](965b918))
* **dependencies:** upgrade to [jsii 0.7.6](https://github.com/awslabs/jsii/releases/tag/v0.7.6)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants