-
Notifications
You must be signed in to change notification settings - Fork 41
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
(JS) Expose handler function type to allow manual exporting of Lambda handler #248
base: main
Are you sure you want to change the base?
Conversation
… handler Related to typelevel#246
ea4f2af
to
e175631
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for starting this!! If you're really brave I guess ideally we would have some integration tests against the actual AWS JS runtime that verify it works for both CommonJS and ESModules.
final def main(args: Array[String]): Unit = | ||
js.Dynamic.global.exports.updateDynamic(handlerName)(handlerFn) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess we can remove this now :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can remove it if you want, but it would be a breaking change for any existing users. It might be nice to still have the old implementation for CommonJS users. Maybe we can also add a warning or clear error when this is called inside ESModule
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have to think about this. I think I dislike the idea that there are two distinct ways to define JS Lambdas, and "dead" code depending on which you choose (such as handlerName
for ESModules). I think this would be very confusing. Since your approach words for both, I'd rather buy-in all the way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alright, I suppose a breaking change like this is better to do early in the life of a library. If I have your permission, I'll remove the related code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Exactly. Please go ahead with the change, although maybe we should make this PR the beginning of an v0.2.x series since this is a significant change (ignoring the fact that 0.1.x hasn't materialized a stable release 😅). You can bump the tlBaseVersion
in the build to signify this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. I don't think I've missed anything, but you are welcome to double-check me :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! I'm afraid the example project will also need updating :) To keep it cross-compiling with JVM I think we can add a @JSExport
stub.
https://github.com/scala-js/scala-js-stubs/
// This would be exported with `@JSExportTopLevel("handler")` | ||
def impl: HandlerFn = handlerFn |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we're not exporting it, what is this actually testing?
To verify the export works, our test should be able to call the exported method without knowing about the CountingIOLambda
type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I suppose this only tests that impl
calls handlerFn
which calls handler
. Which verifies that the handler works when implemented by the class. I don't think you can explicitly call an export inside a unit test. If you have any ideas about how to approach I'd be happy to hear it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've now added a new sbt scripted test to replace this one. It's similar to the existing one, except it tests the exported handler
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think you can explicitly call an export inside a unit test. If you have any ideas about how to approach I'd be happy to hear it
For the record, I'm pretty sure you can :) conceptually an "exported" function is equivalent to a function defined in JavaScript land. So we can write a facade for it, and call it, without knowing that it is in fact defined in Scala!
I have no idea how I'd even start on this 😅 |
If you want to do this 😁 start by making a new project with feral and figure out how to run it against SAM locally. Then, write those commands into an sbt task. Then, we make that into a scripted test. Some of my old work here might be helpful: Anyway just driving by, sorry, will come back later with another review pass :) thanks for all your work! |
I wonder if instead of dealing with SAM it would be easier to work with the Node.js runtime directly. |
Cool, I did some investigation. It seems the trick is to install aws-lambda-ric and and aws-lambda-rie. Then we start the lambda like this:
where exports.handler = async (event, context) => {
return 'Hello World!';
} which can be invoked like:
No pressure to take this on :) but given my previous hiccups with exports I would like to add this integration test just to be sure that everything works. |
Hmm, this is confusing. |
Ah, instead of installing the ric and rie seems we can directly invoke the docker image. https://hub.docker.com/r/amazon/aws-lambda-nodejs |
Related to #246
Needs some more docs, maybe some further (manual) testing, and possibly an entirely different implementation. But I wanted to open this PR to have an example and get the discussion flowing.
With this, you can implement and export your lambda as follows: