Tuesday, March 26, 2019

Documented JSON Classes

Looking through the PeopleTools 8.57 Feature Overview document, you may have noticed that 8.57 now includes support for several JSON classes as well as PeopleBooks documentation. As Chris Malek showed us a couple of years ago, the classes listed in the Feature Overview document are not new. What is new is the keyword Support and PeopleBooks documentation. Using the documentation, I was able to generate a sample on PeopleTools 8.57:

Local JsonBuilder &jbldr = CreateJsonBuilder();
Local string &json;

If &jbldr.StartArrayReturnsTrue("Employees") Then
   REM Empl 1;
   If &jbldr.StartObjectReturnsTrue("Employee") Then
      If &jbldr.StartObjectReturnsTrue("Name") Then
         &jbldr.AddProperty("First", "Jim");
         &jbldr.AddProperty("Last", "Marion");
         &jbldr.AddProperty("Middle", "J");
         &jbldr.EndObject("Name");
      End-If;
      &jbldr.AddProperty("ID", 123456);
      &jbldr.EndObject("Employee");
   End-If;
   
   REM Empl 2;
   If &jbldr.StartObjectReturnsTrue("Employee") Then
      If &jbldr.StartObjectReturnsTrue("Name") Then
         &jbldr.AddProperty("First", "Lucy");
         &jbldr.AddProperty("Last", "McGillicuddy");
         &jbldr.AddProperty("Middle", "");
         &jbldr.EndObject("Name");
      End-If;
      &jbldr.AddProperty("ID", 789123);
      &jbldr.EndObject("Employee");
   End-If;
   &jbldr.EndArray("Employees");
End-If;

&json = &jbldr.ToString();

MessageBox(0, "", 0, 0, &json);

Alternatively, we can build JSON structures using JsonObject and JsonArray directly, but I like the way the JsonBuilder structures code so that child items appear indented, etc. Notice the code above begins the JSON structure with an array? Here is the output. Notice the root node is an object, not an Array:


Even though my very first call to JsonBuilder was to start an Array, it started an Object. What if you just want an array as the outer node? We can extract the array from the JsonBuilder RootNode using the following:

&jbldr.GetRootNode().GetJsonObject().GetJsonArray("Employees");
What if we want to format the code? First, I don't recommend formatting code you will transmit to external systems as white-space compressed JSON is preferred for data transmission. But formatting for debugging purposes is perfect. We can format JsonBuilder output using the JsonGenerator class. Here is a fragment that will format the JsonBuilder result:
Local JsonGenerator &jgen = CreateJsonGenerator();
&jgen.SetRootNode(&jbldr.GetRootNode());
&json = &jgen.ToString();

One thing to note is that JsonBuilder will let you generate invalid JSON. The parameter to StartXxxReturnsTrue is the name of the node to create. If we start the first node with a zero-length string: &jbldr.StartArrayReturnsTrue(""), then the generated JSON will include curly brace object notation, but no property name before the Array start.

As I look through the documentation for 8.57, I see every Json class method and property documented, but what about the CreateJsonXxx functions? Anyone find documentation for these functions? Did I miss something?

As Chris pointed out, these JSON Classes have been in PeopleTools since 8.55.11. Assuming that just the documentation is new and not the classes, I ran all of this code on 8.56 and it works without modification.

At jsmpros, we teach JSON strategies through our Integration Broker and PeopleTools Delta courses. Are you interested in learning more? Contact us to schedule your next PeopleTools training session.

9 comments:

Daniel said...

Thank you Jim for this post, it is extremely helpful. I was running into barriers trying to use delivered PeopleSoft Document / Message functionality in conjunction with third-party client requirements. This is an excellent alternative and I see this creating much fewer objects that the client needs to maintain and migrate.

Jim Marion said...

@Daniel, great point on the metadata maintenance front.

Manoj said...

Finally!, the Document object is so cumbersome to maintain and buggy.

Tom Williams Jr. said...

Thanks Jim. This has been very helpful for me to build my first JSON message. I have been able to view my message and it looks good.

Now I just have to Post my JSON message to an IB ServiceOperation.

Could you direct me to the best reference for this? In PeopleBooks I still see very little documentation that walks me through creating a JSON message and then results in a Publish transaction. I'm trying to publish to a Rest Service for the first time and all I have found is how to pass rowsets to a message and then pass that rowset to a %IntBroker.Publish().

Tom

Patti said...

I'd be interested in this as well Tom. I'm finding the document technology to be quite cumbersome and I have not been able to get it to work correctly, especially when trying to use collections.

ps_dips said...

On PT 8.57.08. I am working on building a REST web service and following is my JSON request that I am trying to submit using the PATCH method.

[
{
"path": "some_string_value",
"op": "some_string_value",
"value": "some_string_value"
}
]

Any ideas if PT document technology supports building this JSON message? What I have tried is in Document builder, put a collection under the root node and then referenced a child compound which has the primitives. That gets me the following.
{
"some_tag":[
{
"path":"some_string_value",
"op":"some_string_value",
"value":"some_string_value"
}
]
}

Due to the extra tags the message is rejected by the 3rd party web service. So let me know if you have any thoughts on what can I try to get the document/message in the correct format.

Thanks
DS

Jim Marion said...

@ps_dips, absolutely!! You can build any valid JSON structure, but not through the Documents module. It is very restrictive. Instead, use the JSON classes mentioned here or use the options in this post: https://jjmpsj.blogspot.com/2018/06/101-ways-to-process-json-with-peoplecode.html

Gowtam said...

Jim, I'm facing the same issue as @ps_dips mentioned above. Is there any easy way to add array to the outer node. I am able to get the structure requested by 3rd party web service but its lagging square brackets.

Thanks!

Jim Marion said...

@Gowtam, yes. The PeopleSoft behavior is to wrap everything in curly brackets (object notation), not arrays. You can extract the array from the object, and then ToString the array to get the final result.