-
Notifications
You must be signed in to change notification settings - Fork 1.5k
JAVA-3292: Add a Codec for converting directly to and from a JSON string #572
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
Conversation
* | ||
* @since 4.2 | ||
*/ | ||
public class JsonString { |
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 wasn't sure where to put this file. This folder contains json stuff, but it's not that related to the purpose of this file. I was debating between this folder and its parent folder.
-
I decided against providing equals and hashcode methods because I thought users shouldn't really keep JsonStrings, they should just use them to access the string. Do you agree with this decision?
-
I don't have any unit tests for this class. Is this okay for simple wrapper classes like 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.
-
I think this location is fine.
-
I would add an equals and hashcode for comparison purposes - we don't know how users will use this class and if they will always unbox it directly.
-
Yes lets add some unit tests.
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
Forgot to run a patch when I first put it up, here it is: https://spruce.mongodb.com/version/5f510b9c7742ae610dba68c5/tasks |
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.
Some comments and nits.
* Construct a JsonStringCodec with default JsonWriterSettings | ||
*/ | ||
public JsonStringCodec() { | ||
this(JsonWriterSettings.builder().outputMode(JsonMode.RELAXED).build()); |
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.
Comment (no action required): Seems odd to explicitly set the output mode when the javadoc notes its the default settings.
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 know you said no action required, but I agreed that this seemed weird so I got rid of setting the outputMode explicitly.
* | ||
* @since 4.2 | ||
*/ | ||
public class JsonString { |
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 think this location is fine.
-
I would add an equals and hashcode for comparison purposes - we don't know how users will use this class and if they will always unbox it directly.
-
Yes lets add some unit tests.
package org.bson.json; | ||
|
||
/** | ||
* A wrapper class that holds a JSON string. This class makes decoding straight |
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.
Add a note that it holds a JSON document String. As an array is a valid top level JSON type we should clarify.
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
* | ||
* @param json the JSON string | ||
*/ | ||
public JsonString(final String json) { |
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.
Add a not null check here.
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.
What happens if a user tries to do:
MongoCollection<JsonString> collection.insert(new JsonString("['a', 'b', 'c']"));
Do you think there should be any validation on the String?
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.
Added the null check.
I don't think we should verify if the String is valid JSON because that would hurt performance especially for large JSON strings and the whole purpose of this ticket is to improve performance. I decided to do a middle-ground where we check that the first and last characters are curly braces. My motivation is that this helps them catch obvious bugs where they try to pass in an array for example. My concern with this is that our constructor throws exceptions for certain invalid JSON inputs, but not others so this may be unpredictable to clients. What do you think?
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.
Now I'm wondering if we should call this class something different. Since [1, 2, 3]
(or even 1
?) is valid JSON, should this class be called JsonObjectString
instead, if indeed it will forever be restricted to JSON objects (see https://www.json.org/json-en.html)?
Even if we don't change the name, if we are committing to only supporting JSON objects, then this class can and should implement org.bson.conversions.Bson
. That way, it can be used for query filters, etc.
Alternatively, we could allow any JSON string, not just JSON objects, though currently BsonReader.pipe currently only supports documents
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 (renamed to JsonObject
and implements Bson
)
* | ||
* @param json the JSON string | ||
*/ | ||
public JsonString(final String json) { |
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.
Now I'm wondering if we should call this class something different. Since [1, 2, 3]
(or even 1
?) is valid JSON, should this class be called JsonObjectString
instead, if indeed it will forever be restricted to JSON objects (see https://www.json.org/json-en.html)?
Even if we don't change the name, if we are committing to only supporting JSON objects, then this class can and should implement org.bson.conversions.Bson
. That way, it can be used for query filters, etc.
Alternatively, we could allow any JSON string, not just JSON objects, though currently BsonReader.pipe currently only supports documents
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.
Looking good. I just have one more request for additional code coverage of the new whitespace checks.
* @param json the JSON object string | ||
*/ | ||
public JsonObject(final String json) { | ||
if (json == null) { |
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.
We have a notNull
helper for this - see org.bson.assertions.Assertions.notNull
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
} | ||
|
||
// Valid whitespace characters according to the json spec: https://www.json.org/json-en.html | ||
if (c != 0x0020 && c != 0x000A && c != 0x000D && c != 0x0009) { |
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 would use Character.isWhitespace
as its what is actually used when parsing json strings and is probably more readable.
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 recommended this approach because it matches the JSON spec. Do you think that's not the behavior of most JSON parsers?
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 suppose, my thoughts were the only parser that actually matters is our own Json reader. Note we don't follow the strictness of the Json Spec, eg we support missing quotes / single quoted values, so thought Character.isWhitespace
was more readable.
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.
Seeing that Character.isWhitespace
matches our own JsonReader's behavior, I agree with Ross and I changed it. Happy to change it back if you strongly disagree @jyemin .
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 ok with this change. You can resolve 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.
LGTM!
LGTM! |
Merged on command line. |
No description provided.