Work with JSON, stop serialization!

Tim Cadenbach
5 min readFeb 21, 2019

--

Catchy title? Yea…didn’t have any other idea :)

“The end of serialization as we know it :) “

Working with API’s is all about JSON these days. Like all these SAAS products, big platforms like Microsoft or Google, all speak Rest and JSON. However, when working with API’s you can find a lot of code in C# or GO or PHP or whatever else that is really odd when you think of it. To be able to generate JSON payload in lets say C# you would generate a ton of new objects, fill those with data just to serialize them at the end and probably have them garbage collected.

While working on a new service, we use to write integrations at Teamwork.com, I actually thought:

„Why write C# or Go code, to (de-) serialize it later if we can do it in JSON directly?“

…and found that its more than possible!

Taken our recent work on MS Teams and AdaptiveCards as an example let me show you what I’m talking about.

In our example we’re sending a person’s status update to MS Teams and we’re using AdaptiveCards for that. The JSON scheme needed for that is pretty complex if you want to create beautiful cards.

The current way , probably used a lot and in a ton of examples:

The old current approach is that you’d generate multiple objects with item collections and a few text fields filled with actual data from your object.

The approach for C# as taken from various samples and guides, for our card, would probably look similar to this:

This is pretty much what you can find in tons of repositories working with adaptive cards these days. In either C# or any other object oriented language.
Its pretty much always the same. Tons of new objects created, tons lines of code just to serialize everything down at the end. All that uses memory, performance and is not really maintainable on top of it. While working on that, I was searching for a better solution as all that really annoyed me. And, guess what, I found one!

Using razor templates to work with JSON

This is pretty much what you can find in our code quite often now:

We have what we call a Card Rendering Service (a singleton services in our ASP.core implementation for those curious to know) which does all the work for us to generate the JSON payload for the adaptive card. The service uses less memory, is a lot faster and way easier to maintain than the old class/object/serialization based approach.

The actual card rendering implementation is (thanks to RazorLight) really simple:

Lets dig a bit deeper into this now.
The call to our service
await _cardservice.RenderCard(templateKey, template, data);
has 3 parameters and is working like usually when using the library . With one clear difference. The library was written for Razor HTML templates…..we’re not even remotely talking about that here!

So what we’re actually passing to RazorLight is this:

templateKey -> usually the lastChangeDate of our template file flat as ddMMYYmmss. RazorLight is caching templates based on the key, so as long as the file does not changed its cached and when the file is changed the cache gets updated. Simple.

template -> our actual JSON template, more on this below

data -> actual object with data we want to render, taken from our example this is the status object containing the status update and the person information.

Based on that, our implementation of the actual adaptive card looks like that now and is stored as string in the database, can be a file or even code..later would obviously don’t really fit the purpose.

As you can see we’re using the JSON template as if it was a normal HTML template with Razor Syntax. We can add our model values wherever we need them in the payload and we can do everything we can possibly do with razor just in JSON.

If you need more complexity..no problem..this is more than possible:

based on that we no longer need to create tons of objects, no serialization and we have easy to manage, hot replace json payloads for adaptive cards.

Lets do some testing

So…to proof my theory of templates being faster we obviously need to run some tests. That said, I built a small ASPCore service with two endpoints “getGenerated” and “getTemplate” (you can see the actual code here)

After that I’ve built a really small net core console app that did nothing but calling the endpoints 20.000 times in a loop while messuring the time.

Here’s the results:

These are just 20.000 iterations so a pretty small sample size but you can already see the templates being a lot faster. The first iteration is slower on the templates as the first call to the RazorLight engine is not cached and thus taking longer to execute.

On just 20.000 iterations, the template way is already 9 seconds faster!

Conclusion

Working with third party api’s like that and especially with more complex schemes like the one needed for AdaptiveCards, makes things a lot more fun and opens a ton of possible things you can do. We can use the AdaptiveCard builder and just copy and paste our code 1:1 without changes needed. This cuts down development time a lot!!
Also, usually when you want to change a payload or when you want to change the layout of your AdaptiveCard or pretty much any JSON payload you sent, you’d probably need to recompile your code, submit data to Github have it built and all that. Takes quite a while, not easy and by far simple. What we can do with our implementation is a lot more flexible. We can store our templates as files but the JSON templates can also be loaded from a database. (We actually store our payloads in the database, so we can change our Adaptive Cards on the fly without recompilation needed!).
When you combine that with templates stored in the database you can easily change your payloads, change the look of an adaptive card and do not need to rebuilt anything. Just update the template or the file whatever approach you prefer.

On the tech side of things you have a lot less objects created, garbage collection is less busy, no more serializing tons of classes.

The API speaks JSON….just working in JSON suddenly makes things a lot easier

Let me know what you think, would love to hear some feedback!

--

--

Tim Cadenbach

Microsoft MVP, Developer Evangelist for DeepL, tech nerd, gamer, husband..loving open source and #AdaptiveCards