Salesforce

How to retrieve and update records from a table through an OpenEdge REST Service using ProDataSets

« Go Back

Information

 
TitleHow to retrieve and update records from a table through an OpenEdge REST Service using ProDataSets
URL NameHow-to-retrieve-and-update-records-from-a-table-through-an-OpenEdge-REST-Service-when-using-ProDataSets
Article Number000183142
EnvironmentProduct: OpenEdge
Version: 11.4 and later
OS: All supported platforms
Question/Problem Description

How to retrieve and update records from a table through an OpenEdge REST Service using ProDataSets
What are the steps to update database records via an OpenEdge REST Service when using a ProDataSet
Example code using an OpenEdge REST web application with a ProDataSet json with before-image data.  

Steps to Reproduce
Clarifying Information
Error Message
Defect Number
Enhancement Number
Cause
Resolution
The OpenEdge REST service uses the WRITE-JSON() and READ-JSON() methods under the covers. 
Before-image support for these methods was first added in OpenEdge 11.4.

The pseudo code syntax  of a JSON string containing a ProDataSet with before-image data is as follows (subject to change in future OpenEdge releases):
{
  "datasetName": {
    "prods:hasChanges" : true, // if no before-image data, property is absent
     "tableName1": [ // after table data
        {
        "prods:id" : "idValue", // unique id matching before and error rows
        "prods:rowState" :  "created | modified",
        "prods:hasErrors" : true,  //if no errors, property is absent
          ... //field values
          ... //nested records if dataset is NESTED
        },
        ...  //more tableName1 records
    ],
    "tableName2": [  //after table data
      {
        "prods:id" : "idValue", // unique id matching before and error rows
        "prods:rowState" :  "created | modified",
        "prods:hasErrors" : true,  //if no errors property absent
          ... //field values
          ... //nested records if dataset is NESTED
      },
        ...  //more tableName2 records
    ],
      ... //more tables/records
    
    "prods:before" : { // before table data
      "tableName1" : [    
        {
          "prods:id" : "idValue", // unique id matching after row
          "prods:rowState" :  "deleted | modified", 
          "prods:hasErrors" : true,  //only for deleted records
                                       if no errors property absent
          ... // field values
        },
        ... // more tableName1 records
      ],
    "tableName2" : [    
        {
          "prods:id" : "idValue",
          "prods:rowState" :  "deleted | modified",
          "prods:hasErrors" : true,  //only for deleted records
                                       if no errors property absent 
          ... // field values
        },
        ... // more tableName2 records
      ],
      ... //more before-tables/records
    },
    "prods:errors" : { // before table ERROR information
      "tableName1" : [ 
        {   
          "prods:id" : "idValue", // unique id matching after row  
          "prods:error" : "error-string"
        },
        ... //errors for more tableName1 records  
      ],
      ... //errors on more tables
    }
}

Where:
  • The JSON object’s name is the ProDataSet name.
  • The "prods:hasChanges" property indicates that the datasetName object contains before-image and possibly error information.
  • The JSON arrays for each temp-table contain the ProDataSet after-table data.  
    • The JSON arrays are structured like what you would see with WRITE-JSON (with nested records, etc.), but each record object might contain the following additional properties (if the after-table record does not have a corresponding before-table record, these properties are absent).
      • "prods:id" – a string property uniquely identifying the record that is used to match up records in the prods:before and prods:errors sections.
      • "prods:rowState" – a string property indicating the row-state of the record. Valid values are "created" or "modified". Modified records have an entry in the prods:before section. Created records do not.
      • "prods:hasErrors" – a boolean property indicating whether the record’s before buffer’s ERROR attribute is true. When true, there is an entry in the prods:errors section containing the error-string value.
  • The “prods:before” object contains the before-table records for the ProDataSet. If there are no before-tables in the ProDataSet, this object is not present in the JSON string. The before-table records are not nested, even if the dataset defines the after-tables in this way. Deleted records are in this section with no corresponding record in the after-table records. Created records do not have an entry in this section.
    • The prods:id property for each before-table row uniquely identifies the record. For modified records, the id matches the corresponding after-table record.
    • Valid values for prods:rowState are "deleted" and "modified".
    • The prods:hasErrors property is present in the before section for deleted records, where applicable.
  • The "prods:error" object contains before-table error-string values for before-table records with ERROR=true.
    • The prods:id property matches that of the corresponding after-table record (modified and created records) or before-table record (deleted records) that has the prods:hasErrors property with a value of true.
    • The prods:error property contains the before-table record’s ERROR-STRING attribute.

Additional JSON Formatting Rules
  1. If any before-image or error data is included in the JSON string, then the prods:hasChages property is required to be the first property in the JSON string, in order to set up the parsing of prods:before and prods:errors sections. This requirement also helps mitigate performance issues for parsing non-before-image JSON strings.
  2. The prods:id property must be included in order to link records in the prods:before, prods:errors and after records sections.
  3. Other than the information above explicit to before-image data, the following general rules apply:
    1. Temp-tables (whether in prods:before, prods:errors, or in the JSON after section) must be JSON Arrays consisting of JSON Objects representing the temp-table rows.
    2. Temp-table fields must conform to the data type mapping rules spelled out in the Working with JSON book.

Example: The following section provides basic steps to demonstrate how this will work in practice. The AppServer procedures used in this example are attached to this article: [AppServer procedures.zip].
  • Create a new REST project or use an existing one within Developer Studio (PDSOE)
  • Configure the AppServer used by the REST project to connect to the Sports2000 database.
  • Add po_server_getdata.p and po_server_process_changes.p to the AppServer's PROPATH.
  • Add po_server_getdata.p as a REST resource using the GET verb (e.g. /PurchaseOrders/{piPONum} ) and map the input and output parameters.
  • Add po_server_process_changes.p as a REST resource using the PUT verb (e.g. /PurchaseOrdersChanges) and map the input-output parameter.
  • Fetch one of the purchase orders by calling po_server_getdata.p from the REST client using an HTTP GET:
Example:
http://localhost:8980/RESTTestProjectService/rest/RESTTestProjectService/PurchaseOrders/8001
  • ​Example: HTTP GET purchase orders
 
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=<ID>; Path=/RESTTestProjectService/; HttpOnly
Date: < date time >
Content-Type: application/json
Content-Length: 552

{
    "response" : {
        "dsPO" : {
            "dsPO" : {
                "ttPurchaseOrder" :
                [{
                        "PONum" : 8001,
                        "DateEntered" : "19980505",
                        "SupplierIDNum" : 1,
                        "ReceiveDate" : "19980729",
                        "POTotal" : 0.0
                    }
                ],
                "ttPOLine" :
                [{
                        "PONum" : 8001,
                        "LineNum" : 1,
                        "ItemNum" : 3,
                        "Price" : 16.55,
                        "Qty" : 3,
                        "Discount" : 0,
                        "ExtendedPrice" : 49.65
                    }, {
                        "PONum" : 8001,
                        "LineNum" : 2,
                        "ItemNum" : 4 5,
                        "Price" : 81.0,
                        "Qty" : 5,
                        "Discount" : 0,
                        "ExtendedPrice" : 405.0
                    }, {
                        "PONum" : 8001,
                        "LineNum" : 3,
                        "ItemNum" : 46,
                        "Price" : 317.0,
                        "Qty" : 2,
                        "Discount" : 0,
                        "ExtendedPrice" : 6 34.0
                    }, {
                        "PONum" : 8001,
                        "LineNum" : 4,
                        "ItemNum" : 47,
                        "Price" : 11.77,
                        "Qty" : 5,
                        "Discount" : 0,
                        "ExtendedPrice" : 58.85
                    }
                ]
            }
        }
    }
}
  • Update the quantity (Qty) of the records containing LineNum 1, 2 and 4 with a PUT request:
PUT http://localhost:8980/RESTTestProjectService/rest/RESTTestProjectService/PurchaseOrdersChanges HTTP/1.1
User-Agent: Fiddler
Accept: application/json
Host: localhost:8980
Content-Length: 1521

{
    "request": {
        "dsPO": {
            "dsPO": {
                "prods:hasChanges": true,
                "ttPOLine": [{
                    "prods:id": "ttPOLine20736",
                    "prods:rowState": "modified",
                    "PONum": 8001,
                    "LineNum": 1,
                    "ItemNum": 3,
                    "Price": 16.55,
                    "Qty": 11,
                    "Discount": 0,
                    "ExtendedPrice": 49.65
                },
                {
                    "prods:id": "ttPOLine20737",
                    "prods:rowState": "modified",
                    "PONum": 8001,
                    "LineNum": 2,
                    "ItemNum": 45,
                    "Price": 81.0,
                    "Qty": 22,
                    "Discount": 0,
                    "ExtendedPrice": 405.0
                },
                {
                    "prods:id": "ttPOLine20738",
                    "prods:rowState": "modified",
                    "PONum": 8001,
                    "LineNum": 4,
                    "ItemNum": 47,
                    "Price": 11.77,
                    "Qty": 44,
                    "Discount": 0,
                    "ExtendedPrice": 58.85
                }],
                "prods:before": {
                    "ttPOLine": [{
                        "prods:id": "ttPOLine20736",
                        "prods:rowState": "modified",
                        "PONum": 8001,
                        "LineNum": 1,
                        "ItemNum": 3,
                        "Price": 16.55,
                        "Qty": 3,
                        "Discount": 0,
                        "ExtendedPrice": 49.65
                    },
                    {
                        "prods:id": "ttPOLine20737",
                        "prods:rowState": "modified",
                        "PONum": 8001,
                        "LineNum": 2,
                        "ItemNum": 45,
                        "Price": 81.0,
                        "Qty": 5,
                        "Discount": 0,
                        "ExtendedPrice": 405.0
                    },
                    {
                        "prods:id": "ttPOLine20738",
                        "prods:rowState": "modified",
                        "PONum": 8001,
                        "LineNum": 4,
                        "ItemNum": 47,
                        "Price": 11.77,
                        "Qty": 5,
                        "Discount": 0,
                        "ExtendedPrice": 58.85
                    }]
                }
            }
        }
    }
}
  • [Finally]: Call po_server_getdata.p from the HTTP REST client once more to confirm that the changes have been written to the database.
Consider using the Progress JSDO if your REST client is based on JavaScript:
Client side TypeScript library to access Progress® Data Object Services
https://github.com/CloudDataObject/JSDO
Workaround
Notes
Keyword Phrase
Last Modified Date11/6/2025 8:25 PM

Powered by