Closed kjvalencik closed 1 year ago
@dherman @kjvalencik is there anything blocking here that I can help with? I've been suddenly running into a really weird issue that seems related to neon_serde
; I could spend my time and effort debugging and working around that issue but I'd prefer to invest it towards something more useful here if possible.
@antonok-edm that does look like a really strange bug! I may look into it if I get a chance.
As for this PR, I'm going to close it. I've been deliberating over this for a long time and decided that quietly switching to JSON in some circumstances is not the right approach. As demonstrated in your PR, it's already pretty easy for users to use JSON if that's their preference.
I'm going to open a new PR that is direct transcoding (closer to neon-serde) and document the caveats that it may be slower than JSON. Then if optimizations are made available to Node-API (currently, object related ones are private V8 APIs that only built-in JSON can leverage), we can make it faster without changing behavior.
There may still be some benefits of building JSON in, since it's such a common pattern. Do you have any thoughts here? Perhaps something like:
let (Something, Other, String) = cx.args_from_json()?;
There may still be some benefits of building JSON in, since it's such a common pattern. Do you have any thoughts here? Perhaps something like:
let (Something, Other, String) = cx.args_from_json()?;
It doesn't seem like that'd support overloaded signatures (which could be fine, I guess). I think having an equivalent of what I wrote in the json_ffi
mod here would be great though.
We discussed this in our last meeting and the plan is to use a newtype approach similar to axum extractors. Something like:
let (a_string, a_number, Json(other_json)): (String, f64, Json<MyStruct>) = cx.args()?;
You could also have extractors that cover overloaded signatures cases like Either<String, f64>
.
This covers the case where the value is already serialized JSON, but I see in your example it's calling JSON.stringify
first. We could have something that did that, although I'm not sure what to call it (ViaJson
?).
My plan is to first implement this and then bring back serde as an extractor type (and without the hacky fallback to JSON).
Based on https://github.com/neon-bindings/neon/pull/701, but with the following changes:
JSON.stringify
,JSON.parse
andserde_json
on non-primitive valuescx.deserialize_args
for getting a tuple from argumentsQuestions
as
casts acceptable or should we bring in a crate to more accurately capture failures?let (n,) = (u64,);
). Should we include adeserialize_arg
for unary methods to simplify things?FromArg
acceptable in the near term or should we try to make a more genericTryFromJs
?~ Defer for the future.FromArg
may be implemented in the future in terms of the other trait.FromArg
orFromArgs
. They are currently private, but that also hides the docs and make it unclear what types implement them. Should we make them available likeArguments
? Should we make them public with thedocsrs
flag only?~ Expose them just likeArguments
with the methods hidden.T
without a special method (deserialize_arg
) and without conflicting withT: DeserializeOwned
? Maybe with some wrapper type?let Arg(name): Arg<String> = cx.deserialize_args()?
~ The type system is actually telling us [correctly] that the API is ambiguous. What if the function does take a single argument and that argument is a tuple?*For future consideration Now that GAT exist, what might it look like to be able to export function that automatically deserialize arguments and serialize return values?