Tajson

TaJson is a declarative approach to receive, send, transform and store json messages, with setup and maintenance environment done in minutes

You can find the original introduction of TaJson here: https://blog.mdriven.net/introducing-mdriven-tajson/

Creating Json from objects

Easiest is to use AsTaJson to create a Json object graph using a viewmodel as a template.

Creating objectsfrom Json

Given a Json object iterates attributes and associations - matching names in a VMClass-instance, and updates internal hierarchy of VMClass given first attribute as key

The RootObject must be given to the VMClass, after that the json object updates hierachy below.

To facilitate update we look for special things in the ViewModel:

  1. Action <ViewModelColumn>_AddNew will be used to create new objects needed for viewmodel-association with name ViewModelColumn - Action must return created object - if action is not found we will look at type info and create object. Note! the AddNew action MUST add the object to the association.
  2. Action Delete in nesting will be used if found when we need to delete object due to missing in input and merge mode is not in effect
  3. Variable vImportKey:string if found will be updated prior to creating a object - can be used in the _AddNew action to look up existing object
  4. Action CleanUpAction if found on root ViewModelClass (as a Column prepared for action in ViewModel Editor) will be called after the import is finished

When using MergeTaJson and ApplyTaJson they both return a string (large) with a log of the Merge/Apply -log.

Improving performance if updating an existing large dataset

When updating using the default behavior, Tajson will load all objects in the many associations, to be able to look them up based on IDs in the Json structure.

But what if you have millions of objects? That will make updating very slow and might make your server run out of memory.

For these special conditions you add an action named <ViewModelColumn>_Lookup.

Looking at the image below, this is the explanation;

  • A variable holding a collection of the objects you want to update. Here called vclient_invoices.
  • Use that variable as the expression of the many association.
  • Tajson will call the lookup action expecting it to fill the many association. There are many ways to do that, but here the expression will use oclPS to get client invoices.
  • When Tajson calls the lookup action, vImportKey will contain a comma-separated list of the keys from the Json.
  • In the example, the oclPS is called for each key and the resulting object added to the list.
  • vClientID is used to pass the key value to the oclPS expression. See ExecutePS for more information.
  • When the action is done, Tajson proceeds as normal.

Please note that using this feature with ApplyTaJson needs special consideration. ApplyTaJson removes objects from the existing database not found in the Json. To use this feature, the objects need to be present in the list you provide.

Lookup example.png

Special consideration for very large and deep Json structures

When confronted with very large and deep json structures it may be a good idea to split the processing and object creation into multiple smaller parts.

Especially the resolve and set of single links may prove problematic to do for a large number of leaf nodes in a large structure.

To facilitate such splitting of large work into smaller pieces we now allow for a special attribute in TaJSon import (Merge and Apply), the special attribute is RawJSon:string (case sensitive).

When the logic finds a ViewModelColumn named RawJSon in a ViewModel nesting - the current Json text is inserted as a string - this is the JSon for the current level and below.

Example:

Consider this Json:

{
  "SomeString": "Hello",
  "Details": [
    {
      "Attribute1": "1111",
      "Attribute2": "222222",
      "Deep1": [
        {
          "asString": "Deep1",
          "Attribute1": "1111",
          "Deep2": [
            {
              "asString": "Deep2",
              "Attribute1": "222"
            }
          ]
        }
      ]
    }
  ]
}

We want to read this into a model like this:

2019-09-09 21h52 15.png

For this we can use ApplyTaJSon with a ViewModel that looks like this:

2019-09-09 21h54 01.png

If we sometimes get a Json data structure with a 1000 Detail objects and each Detail object has 1000 Deep1 objects and each Deep1 had 1000 Deep2 objects - this would force ApplyTaJson to manage 1000*1000*1000 objects at once and that will not work.

But the first level of only 1000 will not be a problem.

To handle this we make use of the RawJSon attribute in a new ViewModel like this:

2019-09-09 21h59 55.png

If we now import with ViewOneThing_SemiDeep we get a result that looks like this (when we read it back with AsTajson):

{
  "SomeString": "Helloxxx",
  "Details": [
    {
      "Attribute1": "1111",
      "Attribute2": "222222",
      "RawJSon": "{\r\n  \"Attribute1\": \"1111\",\r\n  \"Attribute2\": \"222222\",\r\n  \"Deep1\": [\r\n    {\r\n      \"asString\": \"Deep1\",\r\n      \"Attribute1\": \"1111\",\r\n      \"Deep2\": [\r\n        {\r\n          \"asString\": \"Deep2\",\r\n          \"Attribute1\": \"222\"\r\n        }\r\n      ]\r\n    }\r\n  ]\r\n}"
    }
  ]
}

We can now - in a separate pass - loop through a chunk of "Detail"-objects that has a JSon data structure in its Attribute3 - and run ApplyTajson with this snippet of json and a new ViewModel to do things from here and downwards. This will give a worker - like the MDrivenServer ServerSideJobs plenty of small pieces to work on over an extended time, one by one. And this is a much better way to handle the case of large datasets that could result in billions like 1000*1000*1000.

Read more on usage in Rest Services In MDriven

This page was edited 37 days ago on 03/26/2024. What links here