2.4.0 • Published 2 years ago

crow-api v2.4.0

Weekly downloads
-
License
Apache-2.0
Repository
-
Last release
2 years ago

Crow API

Crow API is an AWS CDK construct meant to speed up the time to market for an API. Crow lets you build an API intuitively based on the file structure of a project.

npm install --save crow-api

Getting Started

Start your application as a normal CDK app

npm install -g aws-cdk
cdk bootstrap # If this is your first cdk app, you will need to bootstrap your AWS account
cdk init app --language javascript

Next, install the Crow API package

npm install --save crow-api

In the lib/ folder generated by the cdk, there should be a single file named <your-app>-stack.js. Create your Crow API construct inside of that file like so

const cdk = require('@aws-cdk/core');
const { CrowApi } = require('crow-api');

class MyAppStack extends cdk.Stack {
  /**
   *
   * @param {cdk.Construct} scope
   * @param {string} id
   * @param {cdk.StackProps=} props
   */
  constructor(scope, id, props) {
    super(scope, id, props);

    // The code that defines your stack goes here
    new CrowApi(this, 'my-api', {});
  }
}

module.exports = { MyAppStack }

Your API will start to take shape as you create folders to define paths and methods (see Example File Structure below). To deploy your API, simply run cdk synth and cdk deploy. Follow the instructions as they are prompted, and you will end up receiving a URL where your API now lives.

Example File Structure

The following file structure is present in this repository and is meant to be an example for setting up an API.

| src/
  | authorizer/
    | index.js
  | v1/
    | book/
      | get/
        | index.js
      | post/
        | index.js
        | crow.json
      | chapters/
        | get/
          | index.js
          | crow.json
    | authors/
      | get/
        | index.js
      | post/
        | index.js
        | crow.json

The preceding file structure will create an API with the following routes:

  • GET /v1/book
  • POST /v1/book
  • GET /v1/book/chapters
  • GET /v1/authors
  • POST /v1/authors

There needs to be an index.js file inside of a folder named after an HTTP method in order for a path to be created. The index.js file needs to export a handler method that will process the payload and return.

Crow API Configuration (using crow.json)

Crow looks for a special file in verb folders (get/, post/, etc.) called crow.json. This file is meant to contain configuration items that make it easy to pass props and other configuration to the AWS CDK constructs used by Crow. An example crow.json file might look something like this

{
  "databaseTables": {
    "primaryTable": "PRIMARY_TABLE_NAME"
  },
  "lambdaConfiguration": {
    "memorySize": 256
  },
  "useAuthorizerLambda": true
}

The keys accepted are outlined below.

databaseTables

The keys of the databaseTables object need to also be passed in as props to the CrowApi construct (see databaseTables under "Crow API Props" for more detail). The key name is what is used to match with the databaseTables prop keys (see databaseTables below) and the value is the name of the environment variable which will be present in the Lambda function running your code.

lambdaConfiguration

The lambdaConfiguration object is passed directly in to the Lambda.Function construct which will be running this directories code. Anything available in the class constructor for the Function can be overridden.

For configuration items that are not simple types (i.e. timeout must be type Duration) use the lambdaConfigurations prop.

Note:

Be care with this configuration item as all configuration here takes precedence over Crow defaults. I suggest not using this configuration item unless you are experienced with the AWS CDK and Lambda.

useAuthorizerLambda

The useAuthorizerLambda boolean tells Crow which methods should first have requests authorized using the authorizer Lambda. This configuration item goes hand-in-hand with the CrowApi construct props: useAuthorizerLambda, authorizerDirectory, and authorizerConfiguration. If this configuration item is false, the method will be open.

Crow API Props

Crow API takes in a few props to help you customize away from defaults.

sourceDirectory

By default, Crow walks through the src directory in the root of the repository to determine routes and methods, but you can change the top level directory by passing in the sourceDirectory prop. The string passed in should not start with or end with a slash (/). For example, src, api/src, or source are all valid options to pass in through that prop.

sharedDirectory

By default, Crow copies the shared directory in the source directory of the repository to all routes and methods, but you can change the name of the shared directory by passing in the sharedDirectory prop. The string passed in should not start with or end with a slash (/) and must be a direct child of the source directory. For example, common or utils are valid but shared/utils is not.

Note:

Each route is responsible for its own dependencies including those used by the shared code. I know this is weird, but I have not taken the time to come up with a convenient way to merge two modules' dependencies yet. This means there should be no dependencies saved in the shared module, please do all of that in the target module.

useAuthorizerLambda

Crow will create and attach an authorizer Lambda to specific methods if requested. The useAuthorizerLambda prop tells the CrowApi Construct that it should create an authorizer Lambda and accepts a boolean value. This is false by default.

authorizerDirectory

Crow will allow for a Lambda authorizer to be created and used by specific methods if requested. The authorizerDirectory prop tells Crow where to find the code for the Lambda authorizer within the source directory which can be specified in the sourceDirectory prop. It expects to find an index.js file that exports a handler function within the authorizerDirectory.

By default, Crow expects to find a directory called src/authorizer containing the authorizer Lambda source if the useAuthorizerLambda prop is true. If a different directory within the source directory should be looked at for this code, it should be specified by passing in a string to the authorizerDirectory prop. The string passed in should not start with nor end with a slash (/). For example, auth or authLambdaSrc are valid.

authorizerConfiguration

The authorizerConfiguration prop is passed directly to the APIGateway.TokenAuthorizer construct which will be in charge of your API's authorization. Anything available in the class constructor for the TokenAuthorizer can be overridden.

Note:

Be care with this configuration item as all configuration here takes precedence over Crow defaults. I suggest not using this configuration item unless you are experienced with the AWS CDK, API Gateway, and Lambda.

createApiKey

By default, Crow does not create an API key associated with the API. If an API key is desired, pass in the createApiKey prop as true.

logRetention

By default, Crow creates log groups for resources it creates and sets the log retention to one week. If a different retention is desired pass in the logRetention prop of enum type RetentionDays. This involves importing the proper package like so

const cdk = require('@aws-cdk/core');
const logs = require('@aws-cdk/aws-logs');
const { CrowApi } = require('crow-api');

class MyAppStack extends cdk.Stack {
  /**
   *
   * @param {cdk.Construct} scope
   * @param {string} id
   * @param {cdk.StackProps=} props
   */
  constructor(scope, id, props) {
    super(scope, id, props);

    // The code that defines your stack goes here
    new CrowApi(this, 'my-api', {
      logRetention: logs.RetentionDays.ONE_MONTH,
    });
  }
}

module.exports = { MyAppStack }

databaseTables

Crow accepts an object of Dynamo DB tables that are used by the individual handlers. The key needs to be the same name as what is given in the crow.json file of the handler. The value for that key needs to be the name of the environment variable in which the table name will be injected. The following is a valid example of the databaseTables prop.

#!/usr/bin/env node

const cdk = require('@aws-cdk/core');
const { TablesStack } = require('../lib/tables-stack');
const { CrowApiStack } = require('../lib/crow-api-stack');

const devEnvironment = {
  account: '123456789012',
  region: 'us-east-1',
};

const app = new cdk.App();

const tables = new TablesStack(app, 'TablesStack', {
  env: devEnvironment,
});


new CrowApiStack(app, 'CrowApiStack', {
  env: devEnvironment,
  sourceDirectory: 'src',
  sharedDirectory: 'utils',
  createApiKey: true,
  databaseTables: {
    primaryTable: tables.primaryTable,
  },
});

It is expected that the TablesStack outputs a Dynamo DB table as this.primaryTable, which is then passed to Crow through the databaseTables prop. For an example of this in action, see the tables-stack.js file in the lib/ folder of this repo.

apiGatewayConfiguration

This props allows for more complex overrides to the API Gateway that fronts your API. The configuration allowed is exactly the same as the LambdaRestApi props.

Note:

Be care with this configuration item as all configuration here takes precedence over Crow defaults. I suggest not using this configuration item unless you are experienced with the AWS CDK and API Gateway.

An example of this prop might look like the following:

#!/usr/bin/env node

const cdk = require('@aws-cdk/core');
const apigateway = require('@aws-cdk/aws-apigateway');
const { TablesStack } = require('../lib/tables-stack');
const { CrowApiStack } = require('../lib/crow-api-stack');

const devEnvironment = {
  account: '123456789012',
  region: 'us-east-1',
};

const app = new cdk.App();

const tables = new TablesStack(app, 'TablesStack', {
  env: devEnvironment,
});


new CrowApiStack(app, 'CrowApiStack', {
  env: devEnvironment,
  sourceDirectory: 'src',
  sharedDirectory: 'utils',
  createApiKey: true,
  databaseTables: {
    primaryTable: tables.primaryTable,
  },
  apiGatewayConfiguration: {
    endpointConfiguration: {
      types: [apigateway.EndpointType.REGIONAL],
    },
  },
});

apiGatewayName

This is a simple prop that names the API Gateway. This is how the API will be identified in the AWS console. The value should be a string without spaces and defaults to crow-api.

lambdaConfigurations

This props allows for more complex overrides to Lambda functions. The prop is an object with keys corresponding to the API path of a Lambda function and a value corresponding to the configuration that should be applied to the Lambda. This prop will override any configuration set in the lambdaConfiguration in the crow.json file. The configuration allowed is exactly the same as the Lambda Function props.

An example of this prop might look like the following:

#!/usr/bin/env node

const cdk = require('@aws-cdk/core');
const apigateway = require('@aws-cdk/aws-apigateway');
const { TablesStack } = require('../lib/tables-stack');
const { CrowApiStack } = require('../lib/crow-api-stack');

const devEnvironment = {
  account: '123456789012',
  region: 'us-east-1',
};

const app = new cdk.App();

const tables = new TablesStack(app, 'TablesStack', {
  env: devEnvironment,
});


new CrowApiStack(app, 'CrowApiStack', {
  env: devEnvironment,
  sourceDirectory: 'src',
  sharedDirectory: 'utils',
  createApiKey: true,
  databaseTables: {
    primaryTable: tables.primaryTable,
  },
  apiGatewayConfiguration: {
    endpointConfiguration: {
      types: [apigateway.EndpointType.REGIONAL],
    },
  },
  lambdaConfigurations: {
    '/v1/book/get': {
      timeout: cdk.Duration.seconds(5),
    },
  },
});
2.4.0

2 years ago

2.3.3

2 years ago

1.0.2

2 years ago

1.0.1

2 years ago

1.0.0

2 years ago

2.3.0

2 years ago

2.2.1

2 years ago

2.1.2

2 years ago

2.2.0

2 years ago

2.1.1

2 years ago

2.3.2

2 years ago

2.3.1

2 years ago

2.2.2

2 years ago

2.1.0

2 years ago

2.0.0

2 years ago

0.1.12

3 years ago

0.1.11

3 years ago

0.1.10

3 years ago

0.1.8

3 years ago

0.1.9

3 years ago

0.1.7

3 years ago

0.1.6

3 years ago

0.1.5

3 years ago

0.1.4

3 years ago

0.1.3

3 years ago

0.1.2

3 years ago

0.1.1

3 years ago

0.1.0

3 years ago