{"id":13505548,"url":"https://github.com/thomasstep/crow-api","last_synced_at":"2026-02-13T02:28:21.011Z","repository":{"id":45219627,"uuid":"373824412","full_name":"thomasstep/crow-api","owner":"thomasstep","description":"Crow API is an AWS CDK Construct that makes creating an API fast and easy by basing the structure on the app's file structure.","archived":false,"fork":false,"pushed_at":"2022-03-29T17:46:46.000Z","size":2202,"stargazers_count":9,"open_issues_count":0,"forks_count":1,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-03-02T01:55:29.374Z","etag":null,"topics":["aws","aws-apigateway","aws-cdk","aws-lambda","cdk"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/crow-api","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thomasstep.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-06-04T11:48:41.000Z","updated_at":"2024-12-22T16:04:22.000Z","dependencies_parsed_at":"2022-07-19T00:02:18.730Z","dependency_job_id":null,"html_url":"https://github.com/thomasstep/crow-api","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomasstep%2Fcrow-api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomasstep%2Fcrow-api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomasstep%2Fcrow-api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomasstep%2Fcrow-api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thomasstep","download_url":"https://codeload.github.com/thomasstep/crow-api/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246262490,"owners_count":20749170,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aws","aws-apigateway","aws-cdk","aws-lambda","cdk"],"created_at":"2024-08-01T00:01:09.706Z","updated_at":"2026-02-13T02:28:15.989Z","avatar_url":"https://github.com/thomasstep.png","language":"TypeScript","funding_links":[],"categories":["Construct Libraries"],"sub_categories":["APIs"],"readme":"# Crow API\n\nCrow API lets you build an API intuitively based on the file structure of a project. Provide API Gateway and Lambda function configurations and crow will build out the appropriate paths and methods to the API Gateway. All created resources are available after initialization. `lambdaFunctions` will expose all Lambda functions created for further operations like adding environment variables and providing permissions.\n\n| `crow-api` version | `aws-cdk` version | Notes                   |\n| ------------------ | ----------------- | ----------------------- |\n| 0                  | 1                 |                         |\n| 1                  | 2                 | Not recommended for use |\n| 2                  | 2                 |                         |\n\nContents:\n- [Getting Started](#getting-started)\n- [Example File Structure](#example-file-structure)\n- [Crow API Props](#crow-api-props)\n  - [`sourceDirectory`](#sourcedirectory)\n  - [`sharedDirectory`](#shareddirectory)\n  - [`useAuthorizerLambda`](#useauthorizerlambda)\n  - [`authorizerDirectory`](#authorizerdirectory)\n  - [`authorizerLambdaConfiguration`](#authorizerlambdaconfiguration)\n  - [`tokenAuthorizerConfiguration`](#tokenauthorizerconfiguration)\n  - [`createApiKey`](#createapikey)\n  - [`logRetention`](#logretention)\n  - [`apiGatewayName`](#apigatewayname)\n  - [`apiGatewayConfiguration`](#apigatewayconfiguration)\n  - [`lambdaConfigurations`](#lambdaconfigurations)\n  - [`lambdaIntegrationOptions`](#lambdaintegrationoptions)\n  - [`models`](#models)\n  - [`requestValidators`](#requestValidators)\n  - [`methodConfigurations`](#methodconfigurations)\n- [Properties](#properties)\n  - [`gateway`](#gateway)\n  - [`authorizer`](#authorizer)\n  - [`authorizerLambda`](#authorizerlambda)\n  - [`lambdaLayer`](#lambdalayer)\n  - [`lambdaFunctions`](#lambdafunctions)\n  - [`models`](#models)\n  - [`requestValidators`](#requestValidators)\n\n## Getting Started\n\n[Start your application as a normal CDK app](https://docs.aws.amazon.com/cdk/v2/guide/getting_started.html)\n\n```sh\nnpm install -g aws-cdk\ncdk bootstrap # If this is your first cdk app, you will need to bootstrap your AWS account\ncdk init app --language typescript\n```\n\nNext, install the Crow API package\n\n```sh\nnpm install --save crow-api\n```\n\nIn the `lib/` folder generated by the `cdk`, there should be a single file named `\u003cyour-app\u003e-stack.js`. Create your Crow API construct inside of that file like so\n\n```typescript\nimport { Stack, StackProps } from 'aws-cdk-lib';\nimport { Construct } from 'constructs';\nimport { CrowApi, ICrowApiProps } from 'crow-api';\n\ninterface IYourAppStackProps extends StackProps {\n  crowApiProps: ICrowApiProps,\n}\n\nexport class YourAppStack extends Stack {\n  constructor(scope: Construct, id: string, props: IYourAppStackProps) {\n    super(scope, id, props);\n\n    const {\n      crowApiProps,\n    } = props;\n\n    const api = new CrowApi(this, 'api', {\n      ...crowApiProps,\n    });\n  }\n}\n```\n\nYour 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.\n\n## Example File Structure\n```\n|-- src/\n    |-- authorizer/\n        |-- index.js\n    |-- v1/\n        |-- book/\n            |-- get/\n                |-- index.js\n            |-- post/\n                |-- index.js\n        |-- chapters/\n            |-- get/\n                |-- index.js\n        |-- authors/\n            |-- get/\n                |-- index.js\n            |-- post/\n                |-- index.js\n```\n\nThe preceding file structure will create an API with the following routes:\n- GET /v1/book\n- POST /v1/book\n- GET /v1/book/chapters\n- GET /v1/authors\n- POST /v1/authors\n\nThere 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 like the following.\n\n```javascript\nexports.handler = async function (event, context, callback) {\n  try {\n    const data = {\n      statusCode: 201,\n    };\n    return data;\n  } catch (uncaughtError) {\n    console.error(uncaughtError);\n    throw uncaughtError;\n  }\n}\n```\n\n## Crow API Props\n\nCrow API takes in a few props to help you customize away from defaults.\n\n#### `sourceDirectory`\n\nBy 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.\n\n#### `sharedDirectory`\n\nBy default, Crow creates a Lambda layer out of the `shared` directory in the source directory of the repository, 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.\n\nThe Lambda layer created will be prepended to any the of the layers passed in through `lambdaConfigurations` and added to all Lambda functions created.\n\n#### `useAuthorizerLambda`\n\nCrow 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.\n\n#### `authorizerDirectory`\n\nCrow 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`.\n\nBy 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.\n\n#### `authorizerLambdaConfiguration`\n\nThe `authorizerLambdaConfiguration` prop is passed directly to the Lambda functions which will be in charge of your API's authorization. The configuration allowed is exactly the same as the [Lambda Function props](https://docs.aws.amazon.com/cdk/api/v2//docs/aws-cdk-lib.aws_lambda.Function.html).\n\n#### `tokenAuthorizerConfiguration`\n\nThe `tokenAuthorizerConfiguration` 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`](https://docs.aws.amazon.com/cdk/api/v2//docs/aws-cdk-lib.aws_apigateway.TokenAuthorizer.html) can be overridden.\n\n**Note:**\n\nBe careful 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.\n\n\n#### `createApiKey`\n\nBy 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`.\n\n#### `logRetention`\n\nBy 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`](https://docs.aws.amazon.com/cdk/api/v2//docs/aws-cdk-lib.aws_logs.RetentionDays.html).\n\n#### `apiGatewayConfiguration`\n\nThis props allows for more complex overrides to the API Gateway that fronts your API. The configuration allowed is exactly the same as the [RestApi props](https://docs.aws.amazon.com/cdk/api/v2//docs/aws-cdk-lib.aws_apigateway.RestApi.html).\n\n**Note:**\n\nBe careful 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.\n\nAn example of this prop might look like the following:\n\n```typescript\n#!/usr/bin/env node\nimport 'source-map-support/register';\nimport * as cdk from 'aws-cdk-lib';\nimport * as apigateway from 'aws-cdk-lib/aws-apigateway';\nimport { CrowApiStack } from '../lib/crow-api-stack';\n\nconst devEnvironment = {\n  account: '123456789012',\n  region: 'us-east-1',\n};\n\nconst app = new cdk.App();\n\nnew CrowApiStack(app, 'CrowApiStack', {\n  env: devEnvironment,\n  apiGatewayConfiguration: {\n    endpointConfiguration: {\n      types: [apigateway.EndpointType.REGIONAL],\n    },\n  },\n});\n```\n\n#### `apiGatewayName`\n\nThis 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`.\n\n#### `lambdaConfigurations`\n\nThis 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. The configuration allowed is exactly the same as the [Lambda Function props](https://docs.aws.amazon.com/cdk/api/v2//docs/aws-cdk-lib.aws_lambda.Function.html).\n\n**Note:**\n\nBe careful 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.\n\nAn example of this prop might look like the following:\n\n```typescript\n#!/usr/bin/env node\nimport 'source-map-support/register';\nimport * as cdk from 'aws-cdk-lib';\nimport { CrowApiStack } from '../lib/crow-api-stack';\n\nconst devEnvironment = {\n  account: '123456789012',\n  region: 'us-east-1',\n};\n\nconst app = new cdk.App();\n\nnew CrowApiStack(app, 'CrowApiStack', {\n  env: devEnvironment,\n  lambdaConfigurations: {\n    '/v1/book/get': {\n      timeout: cdk.Duration.seconds(5),\n    },\n  },\n});\n```\n\n#### `lambdaIntegrationOptions`\n\nThis 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 Integration. The configuration allowed is exactly the same as the [LambdaIntegrationOptions](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_apigateway.LambdaIntegrationOptions.html).\n\n#### `models`\n\nThis prop helps set up the `Model`s used in `methodConfiguration` above. It is an array of `CrowModelOptions` which are the same as [`MethodOptions`](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_apigateway.ModelOptions.html) except that the `modelName` is required. The `Model`s will receive an ID equal to its `modelName` which is why that prop is required. The `IModel` can then be referenced in `methodConfigurations` using its `modelName`.\n\n#### `requestValidators`\n\nThis prop helps set up the `RequestValidator`s used in `methodConfiguration` above. It is an array of `CrowRequestValidatorOptions` which are the same as [`RequestValidatorOptions`](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_apigateway.RequestValidatorOptions.html) except that the `requestValidatorName` is required. The `RequestValidator`s will receive an ID equal to its `requestValidatorName` which is why that prop is required. The `IRequestValidator` can then be referenced in `methodConfigurations` using its `requestValidatorName`.\n\n#### `methodConfigurations`\n\nThis prop allows for more complex overrides to individual methods. The prop is an object with keys corresponding to the API path of a method and a value corresponding to the configuration that should be applied to the method as well as the key `useAuthorizerLambda` which will invoke the authorizer Lambda whenever the method is called. The configuration allowed is almost exactly the same as [`MethodOptions`](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_apigateway.MethodOptions.html) plus the `useAuthorizerLambda` boolean.\n\nThe differences between `MethodOptions` and Crow's `CrowMethodConfiguration` (the type for this prop) is that any value referencing `{ [string]: IModel }` (`MethodOptions.requestModels` and `MethodResponse.responseModels`) has been changed to `{ [string]: string }` and similarly `requestValidator` has been changed from `IRequestValidator` to `string`. The strings that are passed should correspond with the `modelName`s or `requestValidatorName`s used in the [`models`](#models) and [`requestValidators`](#requestvalidators) props (see next sections).\n\n**Note:**\n\nIf `createApiKey` is `true`, then the `apiKeyRequired` parameter will need to be set for the methods needing the API key.\n\nAn example of this prop might look like the following:\n\n```typescript\n#!/usr/bin/env node\nimport 'source-map-support/register';\nimport * as cdk from 'aws-cdk-lib';\nimport { CrowApiStack } from '../lib/crow-api-stack';\n\nconst devEnvironment = {\n  account: '123456789012',\n  region: 'us-east-1',\n};\n\nconst app = new cdk.App();\n\nnew CrowApiStack(app, 'CrowApiStack', {\n  env: devEnvironment,\n  models: [\n    {\n      modelName: 'authorsPost',\n      schema: {\n        schema: apigateway.JsonSchemaVersion.DRAFT4,\n        title: '/v1/authors/post',\n        type: apigateway.JsonSchemaType.OBJECT,\n        required: ['name'],\n        properties: {\n          name: {\n            type: apigateway.JsonSchemaType.STRING,\n          },\n        },\n      },\n    },\n  ],\n  methodConfigurations: {\n    '/v1/authors/post': {\n      apiKeyRequired: true,\n      requestModels: {\n        'application/json': 'authorsPost',\n      },\n    },\n    '/v1/book/get': {\n      useAuthorizerLambda: true,\n    },\n    '/v1/book/post': {\n      apiKeyRequired: true,\n    },\n  },\n});\n```\n\n## Properties\n\nA `CrowApi` construct will give full access to all of the resources it created.\n\n#### `gateway`\nThis is the `apigateway.RestApi` that all of the created Lambda functions sit behind.\n\n#### `usagePlan`\nThis is the `apigateway.UsagePlan` associated with the API Gateway and pre-created API key if that is enabled.\n\n#### `authorizer`\nThis is the `apigateway.IAuthorizer` that is attached to the API Gateway.\n\n#### `authorizerLambda`\nThis is the `lambda.Function` that authorizes API Gateway requests.\n\n#### `lambdaLayer`\nIf the `sharedDirectory` is populated, this is the `lambda.LayerVersion` created for that code. If the `sharedDirectory` is not populated, then this is `undefined`.\n\n#### `lambdaFunctions`\nThis is an object with keys being the API paths and the values being the `lambda.Function`s sitting being them. Continuing off of the example file structure from above, the following would be an example of referencing `GET` `/v1/book/chapters`.\n\n```typescript\nimport { Stack, StackProps } from 'aws-cdk-lib';\nimport { Construct } from 'constructs';\nimport { CrowApi, ICrowApiProps } from 'crow-api';\n\ninterface IYourAppStackProps extends StackProps {\n  crowApiProps: ICrowApiProps,\n}\n\nexport class YourAppStack extends Stack {\n  constructor(scope: Construct, id: string, props: IYourAppStackProps) {\n    super(scope, id, props);\n\n    const {\n      crowApiProps,\n    } = props;\n\n    const api = new CrowApi(this, 'api', {\n      ...crowApiProps,\n    });\n\n    const lambda = api.lambdaFunctions['/v1/book/chapters/get'];\n    lambda.addEnvironment('FOO', 'bar');\n  }\n}\n```\n\n#### `models`\n\nThis is an object with keys being the `modelName`s and values being the `IModel`s created.\n\n#### `requestValidators`\n\nThis is an object with keys being the `requestValidatorName`s and values being the `IRequestValidator`s created.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthomasstep%2Fcrow-api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthomasstep%2Fcrow-api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthomasstep%2Fcrow-api/lists"}