/concise-constructs

A functional-feeling DX for the AWS CDK and other construct libraries

Primary LanguageTypeScriptApache License 2.0Apache-2.0

Concise Constructs

npm version license PRs welcome

A utility for defining constructs without ever needing to think about scope. "Concise" constructs are interoperable with classical constructs. The difference is cosmetic; if concise constructs better-jive with your API-design sensibilities, great! Otherwise, classical constructs are still state of the art.

NOTE: this repo follows SemVer and there is yet to be a major release; the public API can still change.

NOTE: JSII cannot yet package concise constructs for consumption in non-TypeScript CDK projects.


Resources

To execute an example, run npm run example [example-dir] [command] (for example, npm run example graphql-api deploy)

Installation

Node users can install with npm.

npm install concise-constructs

Packaged as CommonJS, alongside corresponding type definitions.

Snippets

Lambda Rest API

import {C} from "concise-constructs";
import * as cdk from "@aws-cdk/core";
import * as lambda from "@aws-cdk/aws-lambda";
import path from "path";

const code = new lambda.AssetCode(path.resolve(__dirname, "lambda"));

const Stack = C(cdk.Stack, (define) => ({
  fn: define`my-fn`(lambda.Function, {
    code,
    handler: "index.handler",
    runtime: lambda.Runtime.NODEJS_12_X,
  }),
}));

const App = C(cdk.App, (define) => {
  define`my-stack`(Stack);
});

new App().synth();
... is equivalent to the following.
import * as cdk from "@aws-cdk/core";
import * as lambda from "@aws-cdk/aws-lambda";
import path from "path";

const code = new lambda.AssetCode(path.resolve(__dirname, "lambda"));

class Stack extends cdk.Stack {
  fn;

  constructor(scope: cdk.App, id: string) {
    super(scope, id);

    this.fn = new lambda.Function(this, "my-fn", {
      code,
      handler: "index.handler",
      runtime: lambda.Runtime.NODEJS_12_X,
    });
  }
}

class App extends cdk.App {
  constructor() {
    super();

    new Stack(this, "my-stack");
  }
}

new App().synth();

SQS + SNS

import {C} from "concise-constructs";
import * as cdk from "@aws-cdk/core";
import * as sqs from "@aws-cdk/aws-sqs";
import * as sns from "@aws-cdk/aws-sns";

const Stack = C(cdk.Stack, (define) => {
  const queue = define`HelloCdkQueue`(sqs.Queue, {
    visibilityTimeout: cdk.Duration.seconds(300),
  });

  const topic = define`HelloCdkTopic`(sns.Topic);

  topic.addSubscription(new subs.SqsSubscription(queue));

  return {queue, topic};
});

const App = C(cdk.App, (define) => {
  const stack = define`my-stack`(Stack);
  stack.queue; // sqs.Queue
  stack.topic; // sns.Topic
});
... is equivalent to the following.
import * as cdk from "@aws-cdk/core";
import * as sqs from "@aws-cdk/aws-sqs";
import * as sns from "@aws-cdk/aws-sns";

class HelloCdkStack extends cdk.Stack {
  queue;
  topic;

  constructor(scope: cdk.App, id: string) {
    super(scope, id, props);

    this.queue = new sqs.Queue(this, "HelloCdkQueue", {
      visibilityTimeout: cdk.Duration.seconds(300),
    });

    this.topic = new sns.Topic(this, "HelloCdkTopic");

    topic.addSubscription(new subs.SqsSubscription(this.queue));
  }
}

class App extends cdk.App {
  constructor() {
    super();

    const stack = new Stack(this, "my-stack");
    stack.queue; // sqs.Queue
    stack.topic; // sns.Topic
  }
}

new App().synth();

Lambda CRON

import {C} from "concise-constructs";
import * as cdk from "@aws-cdk/core";
import * as events from "@aws-cdk/aws-events";
import * as lambda from "@aws-cdk/aws-lambda";
import * as targets from "@aws-cdk/aws-event-targets";

const code = new lambda.AssetCode(path.resolve(__dirname, "lambda"));

const Stack = C(cdk.Stack, (define) => {
  const lambdaFn = define`singleton`(lambda.Function, {
    code,
    handler: "index.handler",
    timeout: cdk.Duration.seconds(300),
    runtime: lambda.Runtime.PYTHON_3_6,
  });

  const rule = define`rule`(events.Rule, {
    schedule: events.Schedule.expression("cron(0 18 ? * MON-FRI *)"),
  });

  rule.addTarget(new targets.LambdaFunction(lambdaFn));
});

const App = C(cdk.App, (define) => {
  const stack = define`my-stack`(Stack);
});

new App().synth();
... is equivalent to the following.
import * as cdk from "@aws-cdk/core";
import * as events from "@aws-cdk/aws-events";
import * as lambda from "@aws-cdk/aws-lambda";
import * as targets from "@aws-cdk/aws-event-targets";

const code = new lambda.AssetCode(path.resolve(__dirname, "lambda"));

class Stack extends cdk.Stack {
  constructor(scope: cdk.App, id: string) {
    super(scope, id);

    const lambdaFn = new lambda.Function(this, "singleton", {
      code,
      handler: "index.handler",
      timeout: cdk.Duration.seconds(300),
      runtime: lambda.Runtime.PYTHON_3_6,
    });

    const rule = new events.Rule(this, "rule", {
      schedule: events.Schedule.expression("cron(0 18 ? * MON-FRI *)"),
    });

    rule.addTarget(new targets.LambdaFunction(lambdaFn));
  }
}

class App extends cdk.App {
  constructor() {
    new Stack(this, "my-stack");
  }
}

new App().synth();

Contributing

See CONTRIBUTING for more information.

License

This project is licensed under the Apache-2.0 License.