r

    ribesg

    3 years ago
    Is there a way to completely prevent the serializer from ever serializing a
    null
    value anywhere?
    s

    sandwwraith

    3 years ago
    What's your use-case?
    r

    ribesg

    3 years ago
    The Algolia API which does not accept
    null
    as a value.
    null
    is different than not present for this API (and a lot of others)
    s

    sandwwraith

    3 years ago
    If you have
    null
    as default value for some variable, you can use
    Json(encodeDefaults = false)
    to drop them during serialization process
    r

    ribesg

    3 years ago
    That’s really not a good solution as I could have other default values than
    null
    that I would like to encode anyway
    It also doesn’t seem to work right now, I’ll have to investigate tomorrow...
    d

    dewildte

    3 years ago
    Is it possible to just avoid the use of
    null
    at all?
    r

    ribesg

    3 years ago
    How? The Algolia API is like it is and I have to use it
    And as I said it’s not the only API doing this. All Json serializers implement a way to ignore nulls for a reason... It’s the same thing for top-level Json array, it’s a bad practice but it’s there and serializers have to implement it
    For this use case I think I have no other choice than implementing a whole custom serializer for a dead simple model.
    Note that I agree with the philosophy of not having implicit optionals, I would like to serialize those null values, but philosophies often forget that there is a real world. And when a whole API does not support null values, I don’t want to use workarounds like putting default values everywhere in my code. An optional key is not a mandatory key with a default value, these are different things.
    egorand

    egorand

    3 years ago
    same goes for Protobuf, null just means don’t serialize the field. so far I’ve been unsuccessful in making this work
    d

    dewildte

    3 years ago
    Can you install an anti-corruption layer?
    Personally I prefer default values.
    I get rid of
    null
    at every opportunity.
    r

    ribesg

    3 years ago
    @dewildte that’s unrelated. You’re talking in a context where you have all the power. That does not happen in the real world
    Most of the time you implement an API you don’t have any control on
    @sandwwraith
    encodeDefaults
    absolutely does not work.
    Is there a tutorial somewhere on how to implement a custom serializer? I’m not sure I understand what a SerialDescriptor is and what I’m supposed to use there
    s

    sandwwraith

    3 years ago
    Well, you can try simpler approach first: serialize things to
    JsonElement
    , then just edit it to filter out nulls
    r

    ribesg

    3 years ago
    Yes, that’s what I used, it works:
    @Serializable
    internal data class SearchQuery(
        val query: String,
        val aroundLatLng: String?,
        val facetFilters: List<FacetFilter>?
    ) {
    
        @Serializer(SearchQuery::class)
        companion object : KSerializer<SearchQuery> {
    
            override val descriptor = object : SerialClassDescImpl(SearchQuery::class.simpleName!!) {
                init {
                    addElement("query")
                    addElement("aroundLatLnt", true)
                    addElement("facetFilters", true)
                }
            }
    
            override fun serialize(encoder: Encoder, obj: SearchQuery) {
                encoder
                    .beginStructure(descriptor)
                    .apply {
                        encodeStringElement(descriptor, 0, obj.query)
                        obj.aroundLatLng?.let {
                            encodeStringElement(descriptor, 1, it)
                        }
                        obj.facetFilters?.let {
                            encodeSerializableElement(descriptor, 2, FacetFilter.serializer().list, it)
                        }
                    }
                    .endStructure(descriptor)
            }
    
            override fun deserialize(decoder: Decoder): SearchQuery {
                throw NotImplementedError()
            }
    
        }
    
    }
    Of course I would prefer to only need the first 4 lines...
    @sandwwraith what do you think of a way to add some kind of interceptor that could act between the JsonElement phase and the String phase, for this case but also potentially many more?
    Because I’m using Ktor and serializing to JsonElement myself then removing nulls every time one or more value is optional doesn’t sound like a more practical solution than the custom serializer to me, unless I missed some kind of interceptor like that that I could setup only once
    s

    sandwwraith

    3 years ago
    Hm, I think it is possible to write such interceptor using ktor pipelines
    d

    dewildte

    3 years ago
    You said my statements are unrelated but an anti corruption layer is directly related.
    r

    ribesg

    3 years ago
    Right, but it’s an overengineered solution to a very simple problem in this case
    d

    dewildte

    3 years ago
    You have system A that takes some data in a manner that makes you unhappy. And you have system B that is nice and pretty. System A and B do not work together correctly so you need an adapter or translater, AKA an anti corruption layer. How is that not going to solve your issue?
    It's like American wall sockets vs UK wall sockets.
    Is it really? A simple mapper is not as complicated as a custom serializer.
    r

    ribesg

    3 years ago
    Note that I didn’t say it was not a solution. It’s even the solution I have to implement anyway, either with a custom serializer or by serializing the model myself into a
    JsonObject
    instance, removing
    null
    values by hand and converting that to
    String
    before I pass it to Ktor as a body.
    It’s just something that the library should do. Because that’s what all Json serializers (but this one) allow, ignoring
    null
    values entirely.
    d

    dewildte

    3 years ago
    Make the change easy and then make the easy change. - Kent Beck It sounds like you could take that approach here.
    Like I said, if null is the problem then remove the null and you have no problem.
    r

    ribesg

    3 years ago
    Good theory but I live in the real world
    d

    dewildte

    3 years ago
    Anyway I tried to be helpful now you are just being snide. Good day to you sir.