Using Serverless Variables from Javascript file that calls API

Hi,
I am trying to use the new serverless 1.3 Javascript support for variables to get my variable-values from a dynamoDB table.

In the blog post the example is mentioned as:

module.exports.fetchApiKey = () => {
  // create / fetch dynamic data here (e.g. call an API)
  return someApiKey;
}

(https://serverless.com/blog/serverless-v1.2.0/?utm_source=Newsletter&utm_medium=Email&utm_campaign=v1.2%20release)

But as soon as I put asynchronous code in there (call an API), the function returns undefined before the call is complete. Can you show me an example how to use the javascript support to get variable-values from an API?

I’ve been trying to do this as well, and it doesn’t look to be possible:

As you can see, it simply calls the function and uses the result immediately. It is not possible to use an async function here.

I haven’t look at the code that’s implementing the external JS files for variables, but if it’s using require then everything has to be synchronous - async calls will not work.

That’s just how require rolls…

I need an async variable lookup as well… it is definitely using require to load the js file as a node module. The reason looking up stack outputs using the sdk or looking up dynamodb tables is out of the question is because serverless is not passing a callback or expecting a Promise :frowning:

Maybe this is a feature request?

1 Like

I’m curious what a concrete use case is for this functionality?

Environment variables aren’t calculated each request, they’re set at deployment time. Why do you need to store your config in a DynamoDB table over a yaml file? Updating the DynamoDB record won’t change the environment variables until the code is redeployed anyway.

e.g. to not store your api-keys in the git repository but have them easily
accessible to your collaborators.

Sounds like you need a pre-build step - isn’t that what rake is for @razbomi? :stuck_out_tongue_winking_eye:

But seriously, you guys all need some kind of pre-build step.
Trying to shoe-horn this in to Serverless sounds like a slippery slope to me.

@matthiasn what you’re describing sounds like something your build system should be taking care of i.e. populating environment variables so that they’re available to the task at hand.

What happens if the async call in your code in your exclude fails? Your deploy fails?
How long should it wait for the async function to return?

Now your Serverless service can fail to deploy due to a failure in an external system that isn’t directly involved in the deploy… :fearful:

I think async requires is planned for JavaScript in the future, but can’t find the RFC right now.
A quick look on NPM show async-require, but it still sounds like a bad idea to me.

1 Like

Background: I need to access to VPC resources. So, I need to get the list of subnet ids, which the VPC stack has as an Output.

I thought that I can avoid the pre-build step and rake by calling the javascript sdk’s describe_stacks inside the javascript variable reference (untill I eyeballed the variable code).

I worked around the async issue using cross-stack references. More specifically, after a couple of forhead slaps, I abandoned the javascript variable reference altogether in favor of Fn::Import (Had to export the output first).

    subnetIds:
      "Fn::Split":
        - ","
        - "Fn::ImportValue": "${self:custom.${self:custom.stage}.vpc}-PrivateSubnetIds"
1 Like

I’m doing this by using a secrets.yml that stores my secrets for each stage. I keep this file out of git so that each developer can easily configure their own environment. I wrote an article explaining it at Keeping Dev Dependencies Out Of Your Serverless Package.

@buggy, thanks for the advice :slight_smile:

+1 for sharing a good cross-stack references example! :tada: