0

Calling out the tech: C#, Newtonsoft.Json.

We have a class which contains a property named SchemaVersion that we use to inform of the Json document version once that object is ultimately serialized in to our CosmosDb.

Currently this property is set in the object class constructor, and for simplicity assume it's "1.0"

So far we've only added to our class & incremented "1.0" to "2.0", and so when we deserialize document not of latest SchemaVersion always want to 'upgrade' it and this is done by simply checking the value of that property..

private string _schemaVersion;
public string SchemaVersion
{
    get => _schemaVersion != "2.0" ? "2.0" : _schemaVersion;
    set => _schemaVersion = value;
}

New objects still have their SchemaVersion set with the object constructor. This feels a bit clunky to me.. but it does the job.

I know though, that there will come a point where we need to refactor the class for some as yet unknown reason. We'll try to avoid this as much as possible.. but i can see it happening.

The challenge then becomes how do we maintain conversions between

  • "1.0" --> "x.0"
  • "2.0" --> "x.0"
  • "3.0" --> "x.0"
  • "4.0" --> "x.0"

Are there any recommended ways in which this could best be handled? The best idea that i have right now is a custom JsonConverter, which i have written before to deserialize unknown Json documents to a specific object based on a property within that document... but i wonder if that is over-complicated as we will always be deserializing into a latest known shape...

I fear that this could get complex quickly if we end up with many versions, and their conversions to the latest version all need to be maintained separately..

0

Given sufficient complexity and time you will eventually need to implement converter classes that convert old versions of the object to new versions.

These converters will have more logic that you can sensibly squeeze into derserialiation classes, so I would avoid any idea of your class being more than a single version.

ie. the schema version, or simply version, should be a constant. I would probaby use the assembly version of the containing model dll.

When you load old versions of the serialised object, check the version before deserialisation and load the appropraite converter for that version.

For simple point releases with no breaking changes that converter class might be a simple default deserialiser to the current version of the class.

But when you get a breaking change you can add the custom logic to switch to your conversion logic for the particular version you are attempting to load (or throw an exception for an unknown version)

  • Are you saying don't try to deal with this in a single class... make the SchemaVersion unchanging within the class, and then have a custom JsonConverter always target the latest one? Is that not going to be the same issue? My thinking is that we won't maintain/keep any of the older version, only keep the class that is the most recent.. and then the first time we deserialize an old json document it gets transformed to the new one.. once. Initially it might be a little bit slow, but it won't ever need to be done again. The latest version will then be serialised to the Db – m1nkeh Oct 14 '18 at 11:45
  • 1
    yes. make the schema version unchanging in the class (once complied) im not sure what you mean by 'same issue' my point is you cant deal with the conversion in the class or the deserialiser. you need that extra conversion layer – Ewan Oct 14 '18 at 11:51
  • ah, gotcha.. sorry i meant 'same issue' i meant to be that it might be slow when attempting to work out "how" to deserialize, which i think probably wasn't the point you were making re: 'squeeze into deserialization class'. I guess i am left with a massive bunch of logic in a custom converter either way... but at least it validates my think that is the way to do... – m1nkeh Oct 14 '18 at 11:55
  • yeah, I think the best approach is to do a mass conversion on your data store to elliminate thr old data, but its not always possible – Ewan Oct 14 '18 at 12:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.