Draft API for connection and template layers for Redis JSON commands#3327
Draft API for connection and template layers for Redis JSON commands#3327Dgramada wants to merge 22 commits into
Conversation
|
If the interfaces are acceptable, I could close this issue and create a separate one that introduces them alongside their implementations and testing. Would you prefer this approach or would you like me to extend this PR? |
I would just rock this PR (continue on from this point). Thank you for the quick turnaround - I was on PTO - sorry for the delay. |
0680f61 to
275ca3e
Compare
…perations. Signed-off-by: Yordan Tsintsov <yordan.tsintsov@redis.com>
275ca3e to
2f2f6d3
Compare
…s. Added connection layer logic for blocking layer. Removed redundant asserts in RedisJsonCommands default methods. Signed-off-by: Yordan Tsintsov <yordan.tsintsov@redis.com>
…urn type in multiple RedisJsonCommands methods. Signed-off-by: Yordan Tsintsov <yordan.tsintsov@redis.com>
…sonCommands overload to RedisConnectionUnitTests. Updated @SInCE to 4.1. Signed-off-by: Yordan Tsintsov <yordan.tsintsov@redis.com>
Signed-off-by: Yordan Tsintsov <yordan.tsintsov@redis.com>
Signed-off-by: Yordan Tsintsov <yordan.tsintsov@redis.com>
Signed-off-by: Yordan Tsintsov <yordan.tsintsov@redis.com>
Signed-off-by: Yordan Tsintsov <yordan.tsintsov@redis.com>
Signed-off-by: Yordan Tsintsov <yordan.tsintsov@redis.com>
…mmands. Signed-off-by: Yordan Tsintsov <yordan.tsintsov@redis.com>
…t-for-connection-and-template-layer
…t-for-connection-and-template-layer
…Unmarked. Signed-off-by: Yordan Tsintsov <yordan.tsintsov@redis.com>
Signed-off-by: Yordan Tsintsov <yordan.tsintsov@redis.com>
| * @see <a href="https://redis.io/docs/latest/commands/json.arrappend/">Redis Documentation: JSON.ARRAPPEND</a> | ||
| * @since 4.2 | ||
| */ | ||
| List<Long> jsonArrAppend(byte @NonNull [] key, @NonNull String path, @NonNull String @NonNull... values); |
There was a problem hiding this comment.
Let's review if the @NonNull String @NonNull... values argument should be of type String or a different approach.
There was a problem hiding this comment.
Lettuce exposes String and JsonValue overloads. Jedis is typed as Object but, at runtime, is invoked with a String and dispatched to its String branch. Both drivers convert values to UTF‑8 bytes and send as is, without Jackson/Gson serialization. Validation happens server-side in the RedisJSON module and the call succeeds if the bytes form a valid JSON document.
Passing raw null as a parameter value throws an exception in both drivers once they start encoding the value.
POJOs would also fail as the class wouldn't pass through an actual JSON serialization.
In my opinion, the best fit would be to accept a String parameter which represents a JSON value.
Example:
"5" -> JSON number
""5"" -> JSON string
"true" -> JSON boolean
""true"" -> JSON string
"{
"firstName": "Rand"
"lastName": "Al'Thor",
"address": {
"name": "Two Rivers"
}
}" -> JSON object where address points to another JSON object value
"{
"firstName": "Rand"
"lastName": "Al'Thor",
"address": "{
"name": "Two Rivers"
}"
}" -> JSON object where address points to a JSON string value
There was a problem hiding this comment.
A plain String doesn't carry sufficient semantics here, I'm afraid. Every caller arriving at this API would end up asking themselves the very same question, having to dive into the driver details in order to reconstruct the actual contract and that's a recurring tax we'd rather not impose in the first place.
This may feel counterintuitive at present, but I tend towards generalizing the JsonValue notion instead (as in JsonOperations.JsonValue). We've effectively arrived at such an abstraction on the template API already; the natural next step is to push the core abstraction down to the connection level quite along the lines of the stream support in org.springframework.data.redis.connection.stream. As things stand, it's really only the JsonValue.as methods that betray a template-API nature.
Revisiting the template API design with our present insights, I'd refine JsonValue towards a JsonResult extends ….connection.json.JsonValue arrangement on the template side, moving the remaining pieces into the connection.json package proper.
JsonValue itself would then define static factory methods: JsonValue.literal(Number) along with int/long/double/String overloads, JsonValue.nullValue(), and JsonValue.ofJson(String) for verbatim JSON. All connection-level methods would accept JsonValue rather than a raw String accordingly.
Let me know what you think; happy to iterate on the specifics.
There was a problem hiding this comment.
Just to clarify, JsonValue will act as a wrapper and won't really do any parsing right? This is a good approach as it gives more leeway for the API if it needs any modification in the future.
Maybe we should use this approach for the JSONPath as well? We could wrap the string path in a JsonPath similarly to how Jedis and Lettuce do.
Signed-off-by: Yordan Tsintsov <yordan.tsintsov@redis.com>
…rently Jedis has a very inconsistent API compared to Lettuce and changes the data type. Added safely encoded strings to JedisJsonCommands for value params Signed-off-by: Yordan Tsintsov <yordan.tsintsov@redis.com>
Signed-off-by: Yordan Tsintsov <yordan.tsintsov@redis.com>
Signed-off-by: Yordan Tsintsov <yordan.tsintsov@redis.com>
Signed-off-by: Yordan Tsintsov <yordan.tsintsov@redis.com>
|
I think we're closing in on a first solid design here. I'd suggest drawing some inspiration from 28f5665 (on the Json branch in this repository), particularly around I'd propose finalizing the |
Signed-off-by: Yordan Tsintsov <yordan.tsintsov@redis.com>
Signed-off-by: Yordan Tsintsov <yordan.tsintsov@redis.com>
Provides a draft version of how the JSON template and connection layer API should look like. The purpose of this PR is to receive feedback and to get a better feeling of what should Spring Data Redis provide for users that would like to use Redis JSON.