I like to use Dependency injection for my non-infr...
# help
r
I like to use Dependency injection for my non-infra code, makes testing much easier - testable code. I'd like to change this to this, but not sure how I can inject from the infra setup: From:
Copy code
import AWS from "aws-sdk"

export async function handler() {
  console.log("Receipt sent!")

  const ssm = new AWS.SSM()

  const paramRet = await ssm
    .getParameter({
      Name: "/dev/password",
      WithDecryption: true,
    })
    .promise()

  console.log("Credentials!:", paramRet.Parameter.Value)

  return {}
}
To a dependency injection pattern/signature like:
Copy code
export async function handler(aws) {
  console.log("Receipt sent!")

  const ssm = new aws.SSM()

  const paramRet = await ssm
    .getParameter({
      Name: "/dev/password",
      WithDecryption: true,
    })
    .promise()

  console.log("Credentials!:", paramRet.Parameter.Value)

  return {}
}
The infra code is:
Copy code
// target function:receipt
    const fun = new sst.Function(this, "Function", { handler: "src/receipt.handler" })
    fun.attachPermissions(["ssm:GetParameter"])

    // create bus
    const bus = new sst.EventBus(this, "Ordered", {
      rules: {
        rule1: {
          eventPattern: {
            source: ["myevent"],
            detailType: ["Order"],
          },
          // targets: ["src/receipt.handler", "src/shipping.handler"],
          targets: [fun, "src/shipping.handler"],
        },
      },
    })
How can the infra setup pass in an argument to the target? Is it possible?
Perhaps I'd need to do something like Partial Application and Currying of the 'fun' variable
Previously using the Serverless Framework, I could use the 'middy' middleware to inject.
f
@Rudi u can’t pass
aws
directly into the handler. You can either wrap around the handler, or use Middy similar to ur SLS setup.
r
Hmm, OK cool - that does help. I'll have to tinker and play around with it for it to sink into my melon 🙂
@Frank My first stab at this ended up with home rolled code. What do you think? Is this the hard way? The pattern I followed is the handler() function wraps the main() function. The handler function looks for a 'di' property (dependency injection) on the context argument. If there is no di property the handler() creates the dependency and adds it to the context.di.ssm property. The end result is I can easily mock out objects in local most just using Jest out of the box.
I try to keep all the business logic as plain old javascript (typescript) than is testable code. Though using this approach there will always be this untested code - as it only runs in a cloud environment (not 100% coverage attainable)