I just released a new version of my extensions for...
# feed
j
I just released a new version of my extensions for kotlinx.serialization. This library provides saner defaults for
Json()
. I've been using this on my own projects for a few years to work around the defaults that are overly strict and problematic if you care about things like forward compatibility/backward compatibility, and generally being lenient with parsing, which IMHO just boils down to good API design practices. The README spells out in detail what my objections are to these defaults. Additionally some convenient extension functions that make working
JsonElement
,
JsonObject
, etc. a bit easier are included. Should work fine with most recent versions of kotlinx.serialization. https://github.com/jillesvangurp/kotlinx-serialization-extensions
s
The strict defaults have proven to be helpful in spotting errors fast; especially for typos.
3
j
Sure, but they break a lot of real world client code for no good reason.
I've been bitten by this a few times to often.
forward compatibility is not optional in APIs
s
Another solution is to do it like twitter and define a new endpoint that delivers are different JSON. So the new client calls https://example.com/api/4/myEndPoint instead of https://example.com/api/3/myEndPoint I find format changes problematic anyways. Another option would be to include a version number in the document and choose the proper parsing logic upon that. Lenient mode just makes it too easy for typos and format errors to slip through.
j
IMHO, being strict about what you send and flexible about what you receive is the most robust and user friendly. We have frequent updates to our APIs and forcing code changes on every client over very minor API changes is very disruptive and competely unnecessary. But of course for people that feel strong about this, they can always just stick with the defaults. I just don't think they are right for most users.
👀 1
e
s
Copy code
4.1.  Fail Fast and Hard

   Protocols need to include error reporting mechanisms that ensure
   errors are surfaced in a visible and expedient fashion.
That often saved me from said typos.
t
You can always run two different
Json
versions, one that fails on debug mode and a mode lenient one in production 🤔
👍 1
s
Indeed. For example use the strict
Json
in unit tests & dev build and deploy the lenient one in production build.
My point is that the default strictness of
Json
is not a flaw or an error. It's helpful and good.
e
less validation in prod is generally a mistake. at scale, production is where most of your errors are going to be, and you need a strategy for that
👍 2
b
I think it depends. If you enter a domain that has organically grown for years or decades, well… you are either lenient in what you accept or you'll never get a foothold. Take ASN.1 and DER for example, specifically X.509: You'd intuitively think that every bit has to be perfect given how critical to security that is, or all hell breaks loose. Turns out: even in that context, some parts of specifications and standards are more of a (rather strict) guideline than an absolute truth, even though the specs leave absolutely no room for interpretation.
e
yeah no. that's how we end up with https://github.com/FiloSottile/BERserk
👍 1
🫣 1
💡 1
b
oh I agree with that too. ASN.1 is a complex beast but it is here to stay. If you want the benefits of DeviceCheck/AppAttest (i.e. remotely establishing trust in one of the hundreds of millions of iPhones in the field) you can only do that with a lenient ASN.1 parser, because the leaf of certificate chain included in the security proof is not to spec. But yeah, ignoring inputs for signature verification can never end well
Also Google messed up on Android and don't follow their own ASN.1 schema and don't get me started on samsung… Still, whenever doing crypto, structurally invalid data should be rejected right away. but if your parser complains whenever it encounters ASN.1 SETs are not sorted… well lets just say it will probably be the only parser of its kind, and not a very popular one
👀 1