Is there any way to define the Function handler in...
# help
s
Is there any way to define the Function handler inline or pass a js function directly to handler instead of a string containing a path to the file? Something like this:
Copy code
import { Function } from "@serverless-stack/resources";
import { APIGatewayProxyEventV2, APIGatewayProxyHandlerV2 } from "aws-lambda";

export const lambdaHandler: APIGatewayProxyHandlerV2 = async (event: APIGatewayProxyEventV2) => {  
  return {
    statusCode: 200,
    headers: { "Content-Type": "text/plain" },
    body: `Your request was received at ${event.requestContext.time}.`
  };
};

new Function(this, "MySnsLambda", {
  handler: lambdaHandler
});
in the docs I found only this way:
Copy code
new Function(this, "MySnsLambda", {
  handler: "src/sns/index.main",
});
t
We were just discussing this as a team, I'm curious what the larger pattern you have in your codebase where you want to do this. Do you basically want to colocate all application + infra code?
s
I'm thinking about two use cases at the moment. 1st one as you said. we are experimenting with component based approach to structure the app, so for example api stacks are not all defined in the 'lib' folder but inside given microservice directory. similarly I would like to have the function definition as part of lambda file, a bit like controller annotations in java spring 2nd is for writing Scripts. In my case script implements very small task, up to 10 lines of code. Would be convenient to write lambda code inline, or at least in the same file and reference as variable. More readable, less typing of string paths
t
Yeah that makes sense. Right now our architecture doesn't allow this unless you want to literally just pass a string of code. Allowing something like this is a bit complicated because we'd need to code split at compile time but it's something we want to keep thinking about
s
understood! thanks for reply
f
Just to chime in here, does this work?
Copy code
export class MainStack extends sst.Stack {
  constructor(scope: <http://sst.App|sst.App>, id: string) {
    super(scope, id, props);

    new sst.Function(this, "Fn", {
      handler: "./MainStack.lambdaHandler",
    });
  }
}

export function async lambdaHandler(event: APIGatewayProxyEventV2): APIGatewayProxyHandlerV2 {  
  ...
};
s
It doesn't - error is something like "Cannot find a handler file for "./MainStack.lambdaHandler"". It works only if I define the full path to the file starting from "src/"
f
What if you changed
./MainStack.lambdaHandler
to
stacks/MainStack.lambdaHandler
or
lib/MainStack.lambdaHandler
wherever ur MainStack.ts is
@Stan quick update: just tried this and it works!
j
Oh that’s an interesting pattern 👀
s
@Frank I see, so every path starting from root folder will work. In my case i keep the api stacks under src/microservices/XXX/XXXStack.ts . Thanks for this suggestion though! I still have long string paths, but I can keep them in lambda file and import whole exported function construct in the api stack
f
src/microservices/XXX/XXXStack.ts
Interesting structure (I know @thdxr would love to see this). I’ve thought about this way of setting up monorepo, where both stack files and lambda files sits in the services folder. I’m curious to hear about ur experience as you add more stacks to the app, and if you come across certain benefit or downside with this approach.