First we will look at a simple REST JSON Post. The screenshot below has the service operation setup. This is the most simple web service. You will notice that:
Template other than /Document Template because we are not passing any parametersCHG_GENERIC.V1 which is a “Nonrowset-based” based messages. This is is not shown.
We plan on posting some simple JSON to this. The HTTP Signature will look like this:
POST http://localhost:8000/PSIGW/RESTListeningConnector/PSFT_CS/CHG_JSON_TEST.v1/
Authorization: Basic UFM6dHJ5aW5nLXNlZS1pZi1JLXBvc3RlZC1teS1wYXNzd29yZC1JLXNlZQ==
Content-Type: application/json
{
"firstName": "Chris",
"lastName": "Malek",
"Region": "Southern California",
"FavoriteDesert": "Pie, any kind"
}The response that comes out of this web services the following.
HTTP/1.1 200 OK
Connection: close
Date: Wed, 02 Dec 2020 04:33:21 GMT
Content-Length: 234
Content-Type: application/json; encoding="UTF-8"
Content-Encoding: gzip
Set-Cookie: JSESSIONID=6zshuetDLvmVT5G55VCUt0su3nVWAn469hsagTQOqg0zHVExziNa!-1985259815; path=/; HttpOnly,psmap=; domain=.c.peoplesoftdemo-1470578694381.internal; path=/
{
"firstName": "Chris",
"lastName": "Malek",
"Region": "Southern California",
"FavoriteDesert": "Pie, any kind",
"META": {
"OPRID": "PS",
"CURRENT_TIME": "2020-12-02 04:33:21.000000",
"TRANSACTION_ID": "81fa5f4b-3457-11eb-9b6b-e783fa52141b",
"DBNAME": "CS92U009"
}
}The handler parses the inbound root JSON object strings and echos any value back out. We also add a “META” object with some information about the run-time environment.
The entire PeopleCode handler for this web service is:
import PS_PT:Integration:IRequestHandler;
class simpleJSONPost implements PS_PT:Integration:IRequestHandler
method onRequest(&msRequest As Message) Returns Message;
end-class;
method onRequest
/+ &msRequest as Message +/
/+ Returns Message +/
/+ Extends/implements PS_PT:Integration:IRequestHandler.OnRequest +/
Local Message &response = CreateMessage(@("Operation." | &msRequest.OperationName), %IntBroker_Response);
Local JsonObject &responseRootJSON = CreateJsonObject();
Local string &requestPayload = &msRequest.GetContentString();
Local JsonParser &parser = CreateJsonParser();
Local boolean &bParseResult = &parser.Parse(&requestPayload);
If &bParseResult = True Then
Local integer &i;
Local JsonObject &jObj = &parser.GetRootObject();
For &i = 1 To &jObj.ChildCount
Local string &propName;
&propName = &jObj.GetPropertyNameAt(&i);
&responseRootJSON.AddProperty(&propName, &jObj.GetAsString(&propName));
End-For;
End-If;
Local JsonObject &JsonObjMETA = CreateJsonObject();
&JsonObjMETA.AddProperty("OPRID", %OperatorId);
&JsonObjMETA.AddProperty("CURRENT_TIME", %Datetime);
&JsonObjMETA.AddProperty("TRANSACTION_ID", &msRequest.TransactionId);
&JsonObjMETA.AddProperty("DBNAME", %DbName);
&responseRootJSON.AddJsonObject("META", &JsonObjMETA);
/* Push the generated XML to the response document */
If &response.SetContentString(&responseRootJSON.ToString()) Then
End-If;
Return &response;
end-method;
With this simple example you can see:
This web service has no:
A common pattern is receiving a top-level JSON array from an API search. Each element has nested objects and arrays:
[
{
"name": "Meowsy",
"species": "cat",
"foods": {
"likes": ["tuna", "catnip"],
"dislikes": ["ham", "zucchini"]
}
},
{
"name": "Barky",
"species": "dog",
"foods": {
"likes": ["bones", "carrots"],
"dislikes": ["tuna"]
}
}
]
To parse this, use GetJsonArray("") on the root object to get the top-level array, then loop through each element:
Local JsonParser &parser = CreateJsonParser();
Local string &jsonString;
/* &jsonString populated from web service or file */
Local boolean &bParseResult = &parser.Parse(&jsonString);
If &bParseResult = True Then
Local JsonObject &jObj = &parser.GetRootObject();
Local JsonArray &rootArray = &jObj.GetJsonArray("");
Local integer &i, &j;
Local JsonObject &rootObject, &foodObject;
Local JsonArray &jsonArrayFavoriteFoods;
Local string &AnimalName, &favoriteFoods;
For &i = 1 To &rootArray.Length()
&rootObject = &rootArray.GetJsonObject(&i);
&AnimalName = &rootObject.GetAsString("name");
/* Get nested object */
&foodObject = &rootObject.GetJsonObject("foods");
/* Get nested array */
&jsonArrayFavoriteFoods = &foodObject.GetJsonArray("likes");
If All(&jsonArrayFavoriteFoods) Then
&favoriteFoods = "";
For &j = 1 To &jsonArrayFavoriteFoods.Length()
If &j = 1 Then
&favoriteFoods = &jsonArrayFavoriteFoods.GetAsString(&j);
Else
&favoriteFoods = &favoriteFoods | ", " | &jsonArrayFavoriteFoods.GetAsString(&j);
End-If;
End-For;
End-If;
/* &AnimalName and &favoriteFoods now contain the parsed values */
End-For;
End-If;
To extract JSON boolean values, use GetBooleanProperty:
Local boolean &bCanBark = &rootObject.GetBooleanProperty("canBark");
If &bCanBark Then
/* This animal can bark */
End-If;
The Parse method on JsonParser will throw an exception on invalid JSON, so you need a try-catch block:
Local JsonParser &parser = CreateJsonParser();
Local string &jsonString;
/* &jsonString may contain invalid JSON */
try
If &parser.Parse(&jsonString) Then
/* Parse Success - process the JSON */
Else
/* Parse returned false */
End-If;
catch Exception &e
/* Invalid JSON - handle the error */
/* &e.ToString() will contain the position and expected tokens */
end-try;
An error message will look something like:
Invalid token [ 8 ] at position [ 45 ], Expected tokens are: [ , ]
If you don’t know the structure of the JSON ahead of time, you can iterate over properties using ChildCount, GetPropertyNameAt, IsJsonArray, and IsJsonObject:
Local JsonObject &jObj = &parser.GetRootObject();
Local integer &i;
Local string &propName, &propValue;
For &i = 1 To &jObj.ChildCount
&propName = &jObj.GetPropertyNameAt(&i);
If &jObj.IsJsonArray(&propName) Then
/* Handle array property */
Else
If &jObj.IsJsonObject(&propName) Then
/* Handle nested object */
Else
/* Simple value - get as string */
&propValue = &jObj.GetAsString(&propName);
End-If;
End-If;
End-For;
GetPropertyType method available, so you cannot easily determine if a simple value is a string, number, or boolean. You can use IsJsonArray and IsJsonObject to detect arrays and objects, but for primitive types you currently have to use GetAsString and parse the result.Look up any record, field, page, or component, audit security, and monitor Integration Broker across every database — in seconds.
A web console built for the PeopleSoft community — operational monitoring, security auditing, and metadata browsing in one tool.
On-demand security and operational reports for your PeopleSoft environment — no client install required.
Research any PeopleSoft object and monitor system health from a single browser tab — no App Designer, no SQL.
Chris Malek is a PeopleTools® Technical Consultant with over two decades of experience. He is available for consulting engagements.
Work with ChrisSWS turns SQL into production REST APIs — ready for AI, modern apps, and partner integrations. One install, unlimited potential.
A powerful PeopleSoft bolt-on that makes REST web services easy. You bring the SQL, SWS handles the rest.
Traditional PeopleSoft web services cost $3,600–$13,000 each to develop. SWS deploys production REST APIs in under 5 minutes through configuration alone.
Turn PeopleSoft data into clean REST APIs for AI integrations, modern applications, and vendor data feeds. Configuration-driven — no PeopleCode required.