-
Notifications
You must be signed in to change notification settings - Fork 130
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
src(templates)!: modify the nodejs event template to accept a cloudevent #356
Conversation
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.
Overall lgtm. The overall cleanup is nice, as is the intent. I have a couple of minor wording suggestions. And of course, you know how I feel about the parameter naming. Holding this open for more input on that.
message: 'No cloud event received' | ||
}; | ||
} | ||
function handle(context, event) { |
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 prefer data
or eventData
as @zroubalik mentioned.
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.
Why?
I know it's just a variable name, but it's obviously important to both of us, so I'm going to reiterate the reasons I gave in slack here:
- The name
data
is not descriptive enough. It's analogous to other poor variable names such asx
orobject
-- it conveys no domain meaning whatsoever. - The name
eventData
is too descriptive. It risks confusion with the CloudEvent envelope'sdata
field, which is an encoded string. The CloudEvent envelope is an implementation detail that I'd prefer we not expose in the function signature. - The name
event
is just right. It represents the domain event reconstituted from the CloudEvent envelope according to itsdata
,datacontenttype
, anddataschema
fields. - The name
event
is as specific as we can get without knowing which domain is triggering the function. This PR is replacing a function that assumed the domain was user verification. And its second parameter was logically nameduser
. It wasn't calleduserData
because of course it has data. Otherwise, it wouldn't be a parameter at all!
I genuinely cannot fathom why you guys feel so strongly about this. My only guess is that you feel your users will be expecting to work directly with CloudEvent envelopes. And that when they see the parameter name, event
, they will expect that it's the envelope. If that's true, then we should be passing the envelope there, not the event reconstituted from its data. Personally, I'd rather have the latter, which is why I stand by the name.
But hey, I like to think I'm reasonable -- sell 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.
Don't know what are anybody else expectations, but when I see event
I expect it's the whole CloudEvent (including id,source,type etc.).
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 am not sure if envelope is good word. Bill once compared CloudEvent to SOAP envelope, but I don't recall the term from CloudEvent spec.
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.
btw data
is optional field for CloudEvent it might be nil
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.
Helping as much as I am! :)
I don't think we should necessarily strive for cross-language consistency. We shouldn't impose conventions in one language due to limitations in another. I doubt any nodejs developers will care about the quarkus templates.
Regarding the term "envelope", I heard @nainaz and @slinkydeveloper use it, and I like it as a way to distinguish between a conceptual event and its digital representation. For me, envelope == CloudEvent. For you guys building the stuff, it seems like event == CloudEvent. Not sure about your users (other than myself).
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.
In the world of CloudEvents, event == CloudEvent
based on my understanding of this sentence in the spec.
An "event" is a data record expressing an occurrence and its context.
The "context" in this sense is all of the event metadata, e.g. source
, type
, id
and the "occurrence" is the data record itself, i.e. event.data
.
Providing event.data
as the second parameter was done as a convenience, assuming that the function developer is primarily interested in the data that was generated by the "occurrence". But maybe there is equal interest in the other event properties as well. For example, source
and type
may be used to filter events or perform conditional actions in the function. If that's the case, I would be in favor of an event
parameter that corresponds to the actual CloudEvent.
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'm +1 on the 2nd parameter being an actual CloudEvent if that's the lingua franca of most users. I'm not a "CloudEvent guy" so I apologize for all the noise around this.
I'm assuming for a 2-argument handler, the js-runtime will pass the CE in the second parameter and it will NOT be in the context.
And for a 1-argument handler, only the context will be passed, and it will include the CE as it currently does.
EDIT: ^^ I now realize that the CE needs to remain in the context, due to the way javascript handles arguments
Correct? Want me to create an issue in the js-runtime for that?
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.
Agree with Lance and Matej, if I read event
I expect a whole CloudEvent
, but I might be biased. And because we are using Knative Eventing, I suppose users (fn developers) will need to know at least some basic stuff about KEventing and it's concepts in order to write the functions properly. So I think that a term CloudEvent
would be at least somehow familiar for users, so eventually they might get the same impression as I do. ie. expect a CloudEvent
in event
parameter.
Not sure if changing the 2nd parameter to be a full CE is somehow useful, I suppose that parameter was introduced so users can easily get the actual data and don't have to parse the CE 🤷♂️
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.
When implementing a Handler with Naina (having no familiarity with the function signatures of the language beforehand), we were both thrown off by the second parameter not being a CloudEvent. It seemed an obvious assumption that the event would be the argument. Or, at least this would be a supported default. I would certainly advocate for that change, while at the same time completely agreeing with Jim that we should not force consistency between languages; instead working to their strengths.
4621487
to
a5b32e7
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.
Looks nice to me! Pending resolution on the CloudEvent parameter and naming of course.
return HTTP.binary(new CloudEvent({ | ||
source: 'function.verifyUser', | ||
type: 'user:verified', | ||
data: user | ||
source: 'event.handler', | ||
type: 'echo', | ||
data: event | ||
})); |
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 with an eye on our related conversation about accepting an actual CloudEvent named event as the second parameter, it may gain some support from its effect on the default implementation. If we assume that the default handler echoes a cloud event, this cleans up nice:
function handle(context, event) {
return event
}
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.
That absolutely appeals to my aesthetic!! :)
However, I kinda dig showing a bit of the HTTP
library, and I think it's important to set the source & type fields on the returned event.
It might be more useful to the new func
user to see data: event.data
though, just to reinforce that the event is an actual CloudEvent
. But I'd rather not do that until after the runtime is changed to do that. As it stands, this template will work with either the current or the future runtime.
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.
Also, if the event source is a broker, won't returning the event result in an infinite loop?
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.
Also, if the event source is a broker, won't returning the event result in an infinite loop?
That's a good question. I suppose only if the function is subscribed via Trigger, and only filtering on event type - and even then, that assume's the broker is not smart enough to deal with 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.
However, I kinda dig showing a bit of the
HTTP
library, and I think it's important to set the source & type fields on the returned event.
function handle(context, event) {
return event.cloneWith({ source: 'echo.fn', type: 'echo' });
}
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.
But I'd rather not do that until after the runtime is changed to do that.
If this lands, nodeshift/faas-js-runtime#96 - will you coordinate with this PR? (TypeScript needs to change as well).
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.
If this lands, boson-project/faas-js-runtime#96 - will you coordinate with this PR? (TypeScript needs to change as well).
Sure, but... define "coordinate" in this context. I think they can each be merged independently. Or I can wait until after #355 lands and adjust those templates, too?
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.
@jcrossley3 I mean, primarily, that this PR is updated to reflect those changes. Due to the fact that these are user facing API changes, we'll also want to update docs/guides/nodejs.md.
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.
Ah, gotcha. I just pushed a commit that updates the nodejs guide.
The result of discussion over here: knative/func#356
The result of discussion over here: knative/func#356
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.
This LGTM. Thank you @jcrossley3 for being so patient with this process. In the end I think this is a nice improvement!
@jcrossley3 I have just realized that the |
Pretty-printing the contents of the event and its envelope for each request. This is handy when invoked as a Knative event sink as some sources, e.g. Kafka, ignore the response body. Co-authored-by: Lance Ball <lball@redhat.com>
This will require a change to the faas-js-runtime, but at least the template won't need to change when that's released
Done |
Pretty-printing the contents of the event and its envelope for each
request. This is handy when invoked as a Knative event sink as some
sources, e.g. Kafka, ignore the response body.