-
Notifications
You must be signed in to change notification settings - Fork 148
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
Handling unions from JSON #16
Comments
Hello, I'll mention this first in case this is sufficient for your use-case: you can easily wrap values to make them valid by using Now, if you would like unions to never be wrapped, you can also achieve that using a custom logical type and type hook (you had the right idea!): var avsc = require('avsc'),
util = require('util');
/**
* Our new union, which will expose its values directly.
*
* This implementation is pretty minimal, we could optimize it by caching the
* underlying union's type names for example.
*
*/
function UnwrappedUnionType(attrs, opts) {
avsc.types.LogicalType.call(this, attrs, opts);
}
util.inherits(UnwrappedUnionType, avsc.types.LogicalType);
UnwrappedUnionType.prototype._fromValue = function (val) {
return val === null ? null : val[Object.keys(val)[0]];
};
UnwrappedUnionType.prototype._toValue = function (any) {
return this.getUnderlyingType().clone(any, {wrapUnions: true});
};
/**
* The type hook in charge of applying our new union type.
*
* We can't just add a `logicalType` attribute in the case of unions since
* their schemas are vanilla arrays.
*
*/
var visited = []; // To keep track of already unwrapped schemas.
function unwrappingTypeHook(attrs, opts) {
if (attrs instanceof Array && !~visited.indexOf(attrs)) {
visited.push(attrs);
return new UnwrappedUnionType(attrs, opts);
}
} To check that it works: var type = avsc.parse(['null', 'string'], {typeHook: unwrappingTypeHook});
var buf = type.toBuffer('hello');
var str = type.fromBuffer(buf); // 'hello' Except perhaps when only dealing with "optional" unions (i.e. which contain |
Thank you very much for the detailled explanation ! Unfortunetly, this does not seems to work for Record Types (or maybe I did something wrong). Here is an example:
Error:
|
You're right; this is tricky to do for nested unions currently. The above implementation won't support that. I'll see what I can do. |
Just released a new version ( I also added an example of how to implement an optional logical type which might be helpful to you. The use of general "unwrapped unions" is still discouraged (see above comment). |
Seems like it's working well, thank you very much for this ! 👍 |
Great :). |
Thanks for this example! I was going to post the same question. I'm using avro for receipt-only in the browser right now, and eliminating the type information to look like "regular" JS objects is what I wanted to be compatible with JSON serialization. It would be awesome to have this built-in at least on the deserialization side. |
@osi - Thanks for the feedback. I agree that it'd be good to have a way to get rid of the wrapping object but I also believe this is currently best left to users to implement (so they can choose the best implementation for their use-case: e.g. if they only have "optional" unions, the simple example above would do, but other assumptions would require another). On a related note: in the future, one of the things I would like to explore is to come up with a subset of Avro for which encoding of unions would always be well-defined without this wrapping object (e.g. with a single number type). |
One nice balance might be to expose the class and function from the example in the public API so it could be used w/o having to cut and paste it. Otherwise, having the default be avro-JSON is totally sensible. |
Hi,
Thanks for this great library!
Quick question: is there a simple way to handle "unions" without having to wrap elements, maybe using Type Hooks or LogicalTypes or something else ?
For example:
My schema:
I've to wrap element with the type:
What i'd like is to be able to simply encode my records without having to wrap them, like this:
Thanks !
The text was updated successfully, but these errors were encountered: