Search code examples
node.jstypescriptazure-functionsazure-http-triggerazure-functions-node.js

Azure Functions Node.js typescript global variable


I have some node.js Azure Functions (httptriggers) coded with Typescript that I secure with a jwt token. After validating my token at the beginning of the funtion, I'd like to store it globally so I can use it in all my child functions. But I'd like my token to be valid only for the current Invokation Context. I don't want to pass the token as parameter to any function that may need it.

Example:

// I'd like to store it like that, but that isn't thread safe, other user may get the same token
export let globalToken : any;

export async function users(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> {

   globalToken = validateToken(request);

   if(request.method === "GET"){
      return { jsonBody: getUsers() };
   }

}


//### In user.service.ts file ###

export const getUsers = () => {

   // so I can use it everywhere like that, without passing it in parameter every time
   return usersData.filter(u => u.userId === globalToken.userId)

}

Any suggestions?


Solution

  • I don't think what you're trying to achieve is doable without some sort of IoC that supports scoped lifecycles. Something like InversifyJS do support scoped lifecycles. I haven't used InversifyJS for Azure Functions before, though, and the samples I could find with my limited Google-foo skills seem experimental at best:

    But the gist of it would be a service which is registered as scoped, and have a public property (either directly or via getter/setter methods) that can store your information (see inRequestScope for registering scoped services in InversifyJS).

    Since the http trigger would be the root of the dependency graph in our case, and have the scoped service as dependency, any other dependencies we inject/resolve from our http trigger should share the same instance. Using the explanation on the about page for inRequestScope (the A -> B -> R, -> C -> R sample), "A" for us would be the HttpTrigger, and "R" would be the scoped service, "B" and/or "C" would be other services, like your user.service.ts.

    I will note that this seems slightly excessive to implement, if all you want to achieve is to avoid having to parse values between methods (personal take). However, if your project is really large, and you have a lot of dependencies, and some of the values you have to parse around is for a dependency several layers deep, then I can understand why you want to avoid it.