https://serverless-stack.com/ logo
#sst
Title
# sst
l

Luke Wyman

07/06/2021, 9:51 PM
Getting the error:
Error: There is already a Construct with name 'SingersApi' in SingersStack [dev-karaoke-singers]
in the following sst/cdk Stack class:
Copy code
import { RemovalPolicy } from '@aws-cdk/core';
import * as sst from '@serverless-stack/resources';

export default class SingersStack extends sst.Stack {
    constructor(scope: <http://sst.App|sst.App>, id: string, props?: sst.StackProps) {
        super(scope, id, props);

        const singersTable = new sst.Table(this, "singers", {
            fields: {
                singer_id: sst.TableFieldType.STRING,
            },
            primaryIndex: { partitionKey: 'singer_id'},
            dynamodbTable: {
                removalPolicy: RemovalPolicy.DESTROY
            }
        });

        const singersApi = new sst.Api(this, 'SingersApi', {
            defaultFunctionProps: {
                environment: {
                    singersTable: singersTable.dynamodbTable.tableName,
                },
            },
        });

        singersApi.addRoutes(this, {
            'POST /karaoke/singers': 'src/services/singers/functions/KAR_SNG_create_singer.handler',
            'GET /karaoke/singers/{singerId}': 'src/services/singers/functions/KAR_SNG_get_singer.handler',
            'GET /karaoke/singers': 'src/services/singers/functions/KAR_SNG_get_all_singers.handler',
            'PUT /karaoke/singers/{singerId}': 'src/services/singers/functions/KAR_SNG_update_singer.handler',
            'DELETE /karaoke/singers/{singerId}': 'src/services/singers/functions/KAR_SNG_delete_singer.handler', 
        });

        singersApi.attachPermissions([singersTable]);

        this.addOutputs({
            'SingersApi': {
                value: singersApi.url,
                exportName: scope.logicalPrefixedName('SingersApi'),
            }
        });
    }
}
It seems having 'SingersApi' in both
const singersApi = new sst.Api(this, 'SingersApi', {
and
Copy code
this.addOutputs({
            'SingersApi': {
                value: singersApi.url,
                exportName: scope.logicalPrefixedName('SingersApi'),
            }
        });
is a no-go. These seem like similar, yet different context meanings of the api parameter. The later is the Key and ExportName in CFN. But what is the same parameter in the
sst.Api
constructor?
f

Frank

07/06/2021, 9:57 PM
Hey @Luke Wyman, it’s the way CDK is structured. Both the Api and the CFN output are direct children of the Stack. And CDK enforces all children have different IDs.
I’d name the output
SingersApiEndpoint
or
SingersApiURL
, if that works for you.
Note, you can keep the exportName the same
l

Luke Wyman

07/06/2021, 9:59 PM
yeah, key and export name can be the same, but you can't have two keys be the same, right?
they're both children at the same level in the heirarchy, even if one is in the resource category, and the other in the exports category.
f

Frank

07/06/2021, 10:01 PM
Yeah, it’s how CDK builds it’s stack “tree”.
l

Luke Wyman

07/06/2021, 10:02 PM
got it. much appreciated 🙂
f

Frank

07/06/2021, 10:02 PM
This is before things get translated to CFN resources.
np!