-
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
Netlify http4s handler #89
Conversation
for { | ||
event <- env.event | ||
method <- Method.fromString(event.httpMethod).liftTo[F] | ||
uri <- Uri.fromString(event.path).liftTo[F] |
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.
Currently this is the relative path. Is that correct or should it be the full URL?
netlify/src/main/scala/feral/netlify/NetlifyHttp4sHandler.scala
Outdated
Show resolved
Hide resolved
2979694
to
02a3609
Compare
netlify-functions/src/main/scala/feral/netlify/facade/Context.scala
Outdated
Show resolved
Hide resolved
02a3609
to
214c957
Compare
netlify-functions/src/main/scala/feral/netlify/IOFunction.scala
Outdated
Show resolved
Hide resolved
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.
IIUC, the only kind of netlify function possible is an http handler? In which case, I think we can bake this in much more. E.g.
- No need for
Event
andResult
types orOption
for the response or implicit decoders/encoders. We can prescribe exactly what these are going to be. - We could even have
IOFunction.Simple
be implemented directly with anHttpRoutes
.
event <- env.event | ||
method <- Method.fromString(event.httpMethod).liftTo[F] | ||
uri <- Uri.fromString(event.path).liftTo[F] | ||
headers = Headers(event.headers.toList) |
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.
So this problem also applies to the AWS lambda which is admittedly half-baked, do we need to include multiValueHeaders
here as well? Also the rawQuery
.
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.
probably so, yeah. I'll check and add them
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.
still not done, todo
netlify-functions/src/main/scala/feral/netlify/facade/Context.scala
Outdated
Show resolved
Hide resolved
There's more - you can have functions triggered by deployment events etc. https://docs.netlify.com/functions/trigger-on-events/ technically, it seems like these have the same interface but they have a common body schema, except there's a "background function" type that might not have to return... |
Huh, interesting. As you point out it seems that the http Event/Response are the common shared interface (idk about the background one, but what's the harm in returning a 204 or something lol). Then (a future PR can) add models for those additional triggers and maybe some convenience builders based on them. |
Co-Authored-By: Arman Bilge <[email protected]>
Co-Authored-By: Arman Bilge <[email protected]>
Co-authored-by: Arman Bilge <[email protected]>
21b7f23
to
43de541
Compare
@@ -31,7 +31,7 @@ private[lambda] trait IOLambdaPlatform[Event, Result] { | |||
js.Dynamic.global.exports.updateDynamic(handlerName)(handlerFn) | |||
} | |||
|
|||
private lazy val handlerFn | |||
protected lazy val 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.
todo: fix this after #116 lands
import cats.effect.IO | ||
import feral.lambda.Context | ||
|
||
object example extends IOFunction.Simple { |
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.
to be removed later
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.
Worth moving to examples?
@@ -17,14 +17,17 @@ | |||
package feral.lambda.facade | |||
|
|||
import scala.scalajs.js | |||
import scala.scalajs.js._ |
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.
nitpick :P
import scala.scalajs.js._ | |
import scala.scalajs.js.| |
context.memoryLimitInMB.toInt, | ||
(context.memoryLimitInMB: Any) match { | ||
case s: String => s.toInt | ||
case i: Int => i |
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.
Hmm, why isn't fatal warnings complaining about this 😆
import io.circe.Decoder | ||
import io.circe.Encoder | ||
|
||
final case class HttpFunctionEvent( |
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.
Let's add a test using this example:
https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-lambda.html
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.
Oh also let's add a KernelSource
for this so the tracing middleware works too.
|
||
object IOFunction { | ||
|
||
abstract class Simple extends IOFunction { |
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.
Can this extend IOLambda.Simple
instead and avoid the repetition?
import cats.effect.IO | ||
import feral.lambda.Context | ||
|
||
object example extends IOFunction.Simple { |
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.
Worth moving to examples?
// Note: This should always be a string, but the Netlify CLI currently passes a number. | ||
// ref: https://github.com/netlify/functions/pull/251 |
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.
Upstreamed again to ashiina/lambda-local#218 but I'm not optimistic.
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.
Fixed and released!
So apparently a netlify {
callbackWaitsForEmptyEventLoop: [Getter/Setter],
succeed: [Function (anonymous)],
fail: [Function (anonymous)],
done: [Function (anonymous)],
functionVersion: '$LATEST',
functionName: '164d0769d4ca9c18ce26562dca3f9e408070c2d1c2b884621e91527e1724e77d',
memoryLimitInMB: '1024',
logGroupName: '/aws/lambda/164d0769d4ca9c18ce26562dca3f9e408070c2d1c2b884621e91527e1724e77d',
logStreamName: '2021/08/03/[$LATEST]d3dabe643c01435bb985e7b0ae5821d0',
clientContext: {
custom: {
netlify: 'eyJpZGVudGl0eSI6eyJ1cmwiOiJodHRwczovL2Fkb3JpbmctYWxiYXR0YW5pLWEyODkwNi5uZXRsaWZ5LmFwcC8ubmV0bGlmeS9pZGVudGl0eSIsInRva2VuIjoiZXlKaGJHY2lPaUpJVXpJMU5pSXNJblI1Y0NJNklrcFhWQ0o5LmV5SmxlSEFpT2pFMk1qYzVOekkxTVRRc0luTjFZaUk2SWpBaWZRLlJGSDVwRDlPUGZUa2lSb3RscXdRekJmbU1JWlF0QWFOVGNkYlVnX2N6WWMifSwidXNlciI6eyJhcHBfbWV0YWRhdGEiOnsicHJvdmlkZXIiOiJlbWFpbCJ9LCJlbWFpbCI6InRlc3RAdGVzdC5jb20iLCJleHAiOjE2Mjc5NzU5NjgsInN1YiI6Ijc3NWE1MzQ0LTBjNmQtNGRjNi05YWM3LWQyZDY0NmUwNzFlYyIsInVzZXJfbWV0YWRhdGEiOnsiZnVsbF9uYW1lIjoiVGVzdCBVc2VyIn19LCJzaXRlX3VybCI6Imh0dHBzOi8vYWRvcmluZy1hbGJhdHRhbmktYTI4OTA2Lm5ldGxpZnkuYXBwIn0='
},
identity: {
url: 'https://adoring-albattani-a28906.netlify.app/.netlify/identity',
token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2Mjc5NzI1MTQsInN1YiI6IjAifQ.RFH5pD9OPfTkiRotlqwQzBfmMIZQtAaNTcdbUg_czYc'
},
user: {
app_metadata: [Object],
email: '[email protected]',
exp: 1627975968,
sub: '775a5344-0c6d-4dc6-9ac7-d2d646e071ec',
user_metadata: [Object]
}
},
identity: undefined,
invokedFunctionArn: 'arn:aws:lambda:us-east-1:375708248955:function:164d0769d4ca9c18ce26562dca3f9e408070c2d1c2b884621e91527e1724e77d',
awsRequestId: '2ee47065-afe2-433f-b88d-3280e25b5ae4',
getRemainingTimeInMillis: [Function: getRemainingTimeInMillis]
} via https://answers.netlify.com/t/could-not-access-user-from-context-inside-netlify-function/41801/6 The bad news is that there does seem to be some custom stuff in This is really annoying. I don't want to give up all the nice sharing though so I have to think what to do about it. Edit: here's how they inject it into the lambda-local emulator: https://github.com/netlify/cli/blob/4e6a448bebf556d11e866d2231eb461db5486063/src/lib/functions/server.js#L12 |
Some additional notes on
|
clearly lost interest in this, I'll close for now but anyone can feel free to take whatever they want from this :) |
Might close #74 in the future.
Instructions for testing:
nix shell nixpkgs#netlify-cli
)sbt fastOptJS
cp netlify/.js/target/scala-2.13/netlify-fastopt/main.js netlify/functions/example.js
(netlify/functions
is the default directory for functions)netlify functions:serve --debug
localhost:9999/.netlify/functions/example