Author Info
Chris Malek

Chris Malek is a PeopleTools® Technical Consultant with two decades of experience working on PeopleSoft enterprise software projects. He is available for consulting engagements.

About Chris Work with Chris
Looking for pain-free PeopleSoft web services? 😀
PeopleSoft Simple Web Services (SWS)

Introducing a small but powerful PeopleSoft bolt-on that makes web services very easy. If you have a SQL statement, you can turn that into a web service in PeopleSoft in a few minutes.

Contents

A PeopleSoft REST Delete Web Service Example

This is a continuation of the REST examples and should be read after you have understood the Simple REST POST Example section. We are going to expand on that article and implement functionality for the client to delete a past POST.

In the previous POST example, the response of a successful POST returned a TRANSACTION_ID at /response/META/TRANSACTION_ID that we assume the clients stored and referenced in the client application. The TRANSACTION_ID was the Integration Broker transaction GUID. We used that GUID as a key in our PS_C_KEY_VALUE table.

The response example looked like this.

<?xml version="1.0"?>
<response>
  <META isMETA="True">
    <OPRID>REST_TEST_USER</OPRID>
    <CURRENT_TIME>2021-03-14-21.24.15.000000</CURRENT_TIME>
    <TRANSACTION_ID>a0e158cd-850b-11eb-a700-cd5c40da7841</TRANSACTION_ID>
    <DBNAME>CS92U009</DBNAME>
  </META>
</response>

This is very common in REST APIs where the server will return a GUID or database IDs that the client must store and know about for future operations on that object. Often times these are integer values that correspond to the database keys on the server. They may also be implemented as GUIDs. In our example case, we are just using the GUID that PeopleSoft generated for us in the original post. If you are developing a “real” REST API then you would probably have some sort of PeopleSoft database key(s) like DEPTID, EMPLID, INSTITUTION, CRSE_ID, etc.

Build the Template Document

You first have to build a document object that will capture the parameters that will be sent inbound to the web service. In this simple example, we will only have one parameter and that will be the GUID that we want to delete. There are some rules about a document that is used as a template.

This document can only contain primitive elements and collection elements. The document cannot contain any imports (compounds) or compound elements. – 8.55 PeopleBooks

One common mistake is thinking of this “Template document” like a request message. This is NOT a request message. It is really just used to parse Query String Parameters or Parameters that may exist in the URL path. I actually hate how this is implemented but we are stuck with what Oracle has given us.

If you are studying this to implement your own web service, you only need a template document if your web service needs to accept and parse query string or path parameters.

First we need to “Add” a Document using the Document Builder.

  • You then add in one “Child Primitive” of string. This will be the parameter that the client will pass in.
  • Since our only delete parameter will be the GUID that we want to delete, we just have one value/primitive in the Document. If your web service has more parameters then more primitives will be here.
  • Be sure to set your length here. If this is set to zero, you will get cryptic error messages trying to call the web service that do NOT always show up in the error logs.

Next you need to create a Message object backed by this document we created. This is a silly step but it seems to be required by PeopleTools.

Here we add the new message object and reference the document we create above.

Once you click add you will see a message object with the same view of the document. This does NOT seem to provide any functionality on top of the Document. I can only assume this is needed based on some internal legacy code structure that was too hard to restructure inside the PeopleTools code. That code is hidden so I can only guess.

Creating the Response Message

In this example, we are going to have the handler generate the response message entirely in PeopleCode. So we will use a “generic” message here that provides nothing but a shell. (This is a required field on the SO configuration.) You can study the encoding chapter. We will NOT be relying on any functionality that a message object may offer. We already created a C_GENERIC.V1 message in a previous chapter so we will use that.

Creating the Service Operation

Next we can create the Service Operation by opening the existing C_REST_TEST Service that we created. There is a section where you can create additional service operations for the different HTTP methods. You have to create new methods from this page.

Once you click add, you will be transferred to the service operation page. You will see that a new Service Operation was created called C_KEYVALUE_DELETE.

  • Template: This has a value of {GUID}. This is very important to match the value here with the Document variable. Do NOT add a / on the front of this. I make this mistake all the time.
  • Document Template: This is the message object created based on the message. I often see people trying to use a request/response message here and that is NOT correct. This is a message type that only is used for they query string or path parameters.
  • Request Message: Notice that the DELETE methods does NOT have a place for a “Request Message”. It is missing from the UI because for a delete all parameters are passed in the query string path or string.
  • Response: For the response message, we added our C_GENERIC.V1 MESSAGE.

Creating the Service Operation Handler

Now we will create a base handler PeopleCode class to process the request. It needs to:

  • Parse the URL path to extract the query string variable of the GUID we want to delete.
  • Delete the actual data
  • Send back a confirmation message.

Some interesting things about the implementation below.

  • Any value can be sent in for the GUID and we will attempt a delete. We are NOT checking to see if it is valid. In some instances, you may want to check if the parameter is valid and send back a 404 if it is NOT valid. If you need to do that then check the Controlling HTTP Status Codes
  • We will capture the number of rows deleted send it out in the response META section.
  • We will always return HTTP Status 200 even if nothing was deleted. Your Delete service may need to behave differently.
  • In the service operation setup there was NOT a “Request Message”, you will still see one referenced here. The IB framework always sends one along. The client does NOT send a payload in the DELETE but the IB code still has the request object behind the scenes that is used to pull out information from the IB framework.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import PS_PT:Integration:IRequestHandler;


class RestDeleteV1 implements PS_PT:Integration:IRequestHandler
   method OnRequest(&msgRequest As Message) Returns Message;
   
end-class;


method OnRequest
   /+ &msgRequest as Message +/
   /+ Returns Message +/
   /+ Extends/implements PS_PT:Integration:IRequestHandler.OnRequest +/
   
   Local Message &response = CreateMessage(@("Operation." | &msgRequest.OperationName), %IntBroker_Response);
   
   /* Parse Request Path */
   
   Local Document &reqDOC;
   
   &reqDOC = &msgRequest.GetURIDocument();
   
   Local string &guid = &reqDOC.GetElement("GUID").value;
   If All(&guid) Then
      SQLExec("DELETE PS_C_KEY_VALUE WHERE IBTRANSACTIONID = :1 ", &guid);
      Local integer &rows = %SqlRows;
   End-If;
   
   /* Setup Output */
   
   Local XmlDoc &xmlDocResponse;
   Local XmlNode &childNode;
   
   &xmlDocResponse = CreateXmlDoc("<?xml version='1.0'?><RESPONSE/>");
   
   Local XmlNode &nxMetaNode, &xnTemp;
   &nxMetaNode = &xmlDocResponse.DocumentElement.AddElement("META");
   
   &xnTemp = &nxMetaNode.AddElement("OPRID").AddText(%OperatorId);
   &xnTemp = &nxMetaNode.AddElement("CURRENT_TIME").AddText(String(%Datetime));
   &xnTemp = &nxMetaNode.AddElement("TRANSACTION_ID").AddText(&msgRequest.TransactionId);
   &xnTemp = &nxMetaNode.AddElement("DBNAME").AddText(%DbName);
   &xnTemp = &nxMetaNode.AddElement("ROWS_DELETE").AddText(String(&rows));
   &response.SetXmlDoc(&xmlDocResponse);
   
   Return &response;
   
end-method;

Linking the Handler Code to the Service Operation

Now we need to link the handler code to the Service Operation. We have done that in the previous REST examples, and will not show how to do that here.

Setting Up Service Operation Security

We need a valid PeopleSoft user to be able to invoke this service operation. We are going to add this service operation to a permission list and valid user. That is covered in both the REST Security and Simple REST GET Example sections and I will assume you have read those sections and I will not cover them here again.

Testing Initial Setup and Debugging

Now let’s call the web service passing a valid GUID from a previous POST. Here is the HTTP Request.

DELETE http://35.236.27.138:8000/PSIGW/RESTListeningConnector/PSFT_CS/C_KEYVALUE.v1/a8c55c77-8fe6-11eb-9543-fa8f30e0d130 HTTP/1.1
Authorization: Basic UkVTVF9URVNUX1VTRVI6QmFkI1Bhc3N3b3JkIzEyMw==

Here is the response from the web service.

HTTP/1.1 200 OK
Connection: close
Date: Sun, 28 Mar 2021 16:59:03 GMT
Content-Length: 199
Content-Type: text/xml; encoding="UTF-8"
Content-Encoding: gzip
Set-Cookie: JSESSIONID=jNV5xlIkSxxh-dYspQFVyQFRdY4NY1vj__xoIiEY7pwMkgaY6ZmM!-7674374; path=/; HttpOnly,psmap=; domain=.c.peoplesoftdemo-1470578694381.internal; path=/

<?xml version="1.0"?>
<RESPONSE>
  <META>
    <OPRID>PS</OPRID>
    <CURRENT_TIME>2021-03-28-16.59.03.000000</CURRENT_TIME>
    <TRANSACTION_ID>e66d666c-8fe6-11eb-9543-fa8f30e0d130</TRANSACTION_ID>
    <DBNAME>CS92U009</DBNAME>
    <ROWS_DELETE>0</ROWS_DELETE>
  </META>
</RESPONSE>

Summary

In this section we showed you an example DELETE REST implementation. You will see it was was similar to both a GET and a POST.