Getting the error: `Error: There is already a Cons...
# sst
l
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
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
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
Yeah, it’s how CDK builds it’s stack “tree”.
l
got it. much appreciated 🙂
f
This is before things get translated to CFN resources.
np!