3

What I try to achieve

Using Jackson for serialization, there is the @JsonRawValue annotation to achieve that a string value is serialized without quotes. For instance, with the following code

data class SomeData {
   @JsonRawValue
   value: String
}

I can serialize SomeData("{}") and obtain:

{ "value": {} }

(Without the annotation it would be { "value": "{}" }.)

I want to achieve the same using Kotlin serialization.

Why do I want that

The reason why I want this is that I get an object via Rest, I store it in a DB, later load it from there and return it back without changing the content. It doesn't concern me what is contained in the object. So I absolutely do not need it to be parsed or deserialized in any way. In the worst case the content is altered somewhere in the process. In the best case it is just some superfluous computation.

What I tried

It seems that there is no corresponding mechanism in kotlinx-serialization that supports this out-of-the box. Looking at the source code, it seems that I would need an instance of class JsonPrimitive (or JsonLiteral) with a String value, but isString set to false, but there is no way to get that.

Another approach may be to write a serializer that serializes the String value without quotes, but I do not know how.

Karsten Gabriel
  • 3,115
  • 6
  • 19
  • It's a good idea to open an issue in the project's GitHub repo: https://github.com/Kotlin/kotlinx.serialization. You'll probably get the best responses there and in the likely case that this is not yet supported, it will be implemented sooner. – user3738870 Nov 14 '22 at 14:12
  • Why do you need a string here? You could also use `JsonElement` to represent "raw JSON" in your data model, which makes it clear. If you only want JSON objects, you can limit it to `JsonObject`. – Joffrey Nov 14 '22 at 14:33
  • It would actually help to have a more complete description of your use case here. Are you parsing some JSON into this data structure? Or do you build it by hand and only intend to serialize it? Or is it parsed and re-serialized and you just don't want to touch this part? Basically the question is why exactly do you store the raw JSON here, how does it get there, and what do you do with it? – Joffrey Nov 14 '22 at 14:35
  • @Joffrey I added my motivation to the description – Karsten Gabriel Nov 14 '22 at 14:45

1 Answers1

2

As of Kotlinx Serialization version 1.4 it is not possible to encode JSON literal strings, without quotes.

However, it will be possible in the next release! https://github.com/Kotlin/kotlinx.serialization/pull/2041#issuecomment-1287049243

For a sneak peek, have a look at the docs on the dev branch

import java.math.BigDecimal

val format = Json { prettyPrint = true }

fun main() {
    val pi = BigDecimal("3.141592653589793238462643383279")

    // use JsonUnquotedLiteral to encode raw JSON content
    val piJsonLiteral = JsonUnquotedLiteral(pi.toString())

    val piJsonDouble = JsonPrimitive(pi.toDouble())
    val piJsonString = JsonPrimitive(pi.toString())
  
    val piObject = buildJsonObject {
        put("pi_literal", piJsonLiteral)
        put("pi_double", piJsonDouble)
        put("pi_string", piJsonString)
    }

    println(format.encodeToString(piObject))
}

pi_literal is encoded literally, without being quoted.

{
    "pi_literal": 3.141592653589793238462643383279,
    "pi_double": 3.141592653589793,
    "pi_string": "3.141592653589793238462643383279"
}
aSemy
  • 5,485
  • 2
  • 25
  • 51