https://serverless-stack.com/ logo
#help
Title
# help
r

Robb Winkle

06/02/2022, 1:19 PM
How is everyone handling running Typescript async functions in their sst app? I'm retrieving some data from DynamoDB that's required to know what to build in each stack. I think the gap in my current approach is the best way to provide the async data to the functional stack. Right now I put an init function which I call from the sst App index.ts module which will run the async process. Each stack init is calling the same module which caches the data from DynamoDB. Ideally I could retrieve the info in the top level App index.ts and inject it into the stacks that need it. I'm just not seeing a way to do it. Here's an example of my current approach which won't scale very well:
Copy code
export default async function main(app: App) {
	await stack1Init();
	await stack2Init();
	app.stack(stack1)
	.stack(stack2)
	.stack(stack3)
}
I could also be doing something that wasn't intended and I'm looking for feedback on that as well. I'm looking for a better way to do this.
It also seems like await on app.stack should return a Promise wrapped response but the var ends up being void
t

thdxr

06/02/2022, 1:24 PM
Are you saying `await app.stack(func)`is not working?
That's likely a bug
btw top level await works now which is maybe the easiest option
r

Robb Winkle

06/02/2022, 1:24 PM
It's not. It ends up being void
Is there a way to provide the context to the App? I may just be missing that in the api
t

thdxr

06/02/2022, 1:25 PM
I actually haven't confirmed this myself but try this
Copy code
const MyAsyncData = await something()

function MyStack() {
  MyAsyncData
}

export default function main() {
  app.stack(MyStack)
}
r

Robb Winkle

06/02/2022, 1:27 PM
Yeah, not sure why I didn't think to try that. I'll do that and let you know
t

thdxr

06/02/2022, 1:27 PM
but to answer your other question the way to inject data is to use functions that return functions
Copy code
function MyStack(args) {
  return function MyStack(ctx) {
    ...args
  }
}

app.stack(MyStack(args))
I should figure out why the return type is void though, async stacks should be awaitable
r

Robb Winkle

06/02/2022, 1:27 PM
If it helps I'm on version 1.2.13
Finally had time to switch to the top level await. I had to adjust my tsconfig.json to enable top level await, but looks like that will be my solution going forward. Here's my tsconfig.json
Copy code
{
  "extends": "@tsconfig/node16/tsconfig.json",
  "include": [
    "stacks"
  ],
  "compilerOptions": {
    "module": "es2022",
    "moduleResolution": "node"
  }
}
Thanks for you help!
c

Chad (cysense)

06/03/2022, 4:16 AM
Probably not helpful, but one thing to mention is that having your stack dependent on external data is considered an anti-pattern in CDK. People in the CDK world would strongly encourage you to not do this. The argument being that your CDK should be deterministic, so instead of a dynamodb call you should have a local config file. Not sure how people in the SST world feel about this
r

Robb Winkle

06/03/2022, 12:48 PM
Thanks for pointing this out and that would have been my preference if it was possible. My use case doesn't lend itself to local configuration data though. I'm deploying a stack automatically for a certain tier of user. So this is running dynamically in a CodePipeline started by an API request. To provide it statically I could probably export the data to s3 or an artifact, but the DynamoDB solution will work for now. I'm open to other suggestions.
c

Chad (cysense)

06/05/2022, 10:56 AM
So we are doing something similar. Instead what we are doing is when a new user is created our database is updated. We then put the user configuration information in a gh repo. In our pipeline we pull the user configuration from the repo and deploy the infra, that way give certain user config + cdk we always get the same output. Everything is versioned controlled so we can roll-back to previous states if need be
3 Views