1

TL;DR: What is the purpose and function of prepare(): void method of AWS CDK's Construct class? How and when am I supposed to use/avoid it?


The documentation on prepare() says:

protected prepare(): void

Perform final modifications before synthesis.

This method can be implemented by derived constructs in order to perform final changes before synthesis. prepare() will be called after child constructs have been prepared.

This is an advanced framework feature. Only use this if you understand the implications.

… but those "implications" are nowhere to be found.


Judging by a couple of AWS CDK projects I saw (such as this one), when AWS CDK constructs and stacks are built, all of their internal structure (mainly, child constructs) is set up exclusively in the constructor() function (this would be a typical example of that).

I don't think this is a good way of using classes, but I couldn't see another way of setting up stacks and constructs for a long time. However, recently I stumbled upon prepare() and its description ("…will be called after child constructs have been prepared"). I guessed, that it is supposed to be used like so:

export class SomeStack extends AWS.Stack {
  prepare() {
    // add constructs
    // set permissions
    // basically, do everything that is done in `constructor()` here: https://github.com/aws-samples/aws-cdk-examples/blob/master/typescript/api-cors-lambda-crud-dynamodb/index.ts
  }
}

… but this doesn't fit very well with the phrasing "perform final modifications" from the method description.

Parzh from Ukraine
  • 7,999
  • 3
  • 34
  • 65

1 Answers1

1

I've got an answer from one of the contributors of aws-cdk.

As they have pointed out, prepare() is deprecated, and it is about to be removed anyway, so no point in using it:

I think the most important implication is constructs you add during the execution of this method will themselves not be prepared (so you shouldn't be adding any constructs that rely on that happening).

prepare is a method of last resort, for constructs to fix up their own state just before rendering in some conditions (for example, to render default values if certain mutator methods did not get called).

prepare() is deprecated and will be removed in v2. I would not suggest relying on it.

As for setting up everything in the constructor, the advice was to treat inner constructs' definitions as part of the initialization of a given parent construct:

I understand you might have psychological aversion to doing a lot of work in the constructor. Try to see construct definitions like a set of declarations that just happen to produce an initialized object (where our Stack definitely has a Table and the compiler can verify that this member got assigned in the constructor so we can rely on this in the rest of the program).

Parzh from Ukraine
  • 7,999
  • 3
  • 34
  • 65