REST input to temp-table?

Posted by Stefan Drissen on 22-Sep-2014 15:21

The URL path mapper / query mapper works fine for simple input parameters. Is it possible to map path / query to a temp-table within a dataset?

Our current soap web service proxies have input context datasets containing the temp-tables of their business entities - this is fine for soap calls. For REST web services it would be nice to be able to map URL path / query variables to temp-table fields within the dataset.

The alternative is to generate all temp-table fields as input parameters - but I would prefer not to have to do this.

Hopefully I'm missing something obvious?

Posted by Srinivas Munigala on 25-Sep-2014 04:48

Even for PATH parameter, you need to map tt object to single path parameter (as shown in attached file).
 
And your request would be as below:
 
http://localhost:8980/ttQueryPath/rest/ttQueryPathService/test/{"Country":"India","Name":"OpenEdge","Address":"iLabs","Address2":"","City":"Hyd","State":"AP","PostalCode":"400005","Contact":"Gloria Shepley","Phone":"(617) 450-0086","SalesRep":"HXM","CreditLimit":66700.00,"Balance":903.64,"Terms":"Net30","Discount":35,"Comments":"This customer is on credit hold.","Fax":"","EmailAddress":""}
 
But, I would suggest to map temp-table / dataset like objects to body instead of path / query parameter as it would be very easy to send json format data in body rather path / query.
 

 
[collapse]
From: Stefan Drissen [mailto:bounce-14941@community.progress.com]
Sent: Thursday, September 25, 2014 12:47 PM
To: TU.OE.Development@community.progress.com
Subject: RE: [Technical Users - OE Development] REST input to temp-table?
 
Reply by Stefan Drissen

I understand the query part.

How should the path be mapped?

From what I see so far, using a temp-table / dataset as input from the path / query is not going to give a usable solution.

Maybe an example based on tt above will help. I have defined the following rest resources:

/lala/{adm_nr}/{debtor} -> /lala/621/1010

/lala/{adm_nr} -> /lala/621?country=NL

/lala -> /lala?country=NL

The first allows me to get one entity using its key.

The second and third allow me to search entities using a partial key (adm_nr = company) and query parameters

The only sensible way I see of achieving this at the moment is to define all input temp-table fields as input parameters.

Is this correct?

Stop receiving emails on this subject.

Flag this post as spam/abuse.

[/collapse]

All Replies

Posted by Srinivas Munigala on 24-Sep-2014 04:58

Yes, you can map path / query to a temp-table within a dataset.

I tried it for temp-table, the client request would be like as below: (I mapped temp-table to "custRecord" Query String Parameter) and it worked for me.

http://localhost:8980/ttQueryPath/rest/ttQueryPathService/test?custRecord={"Country":"India","Name":"OpenEdge","Address":"iLabs","Address2":"","City":"Hyd","State":"AP","PostalCode":"400005","Contact":"Gloria Shepley","Phone":"(617) 450-0086","SalesRep":"HXM","CreditLimit":66700.00,"Balance":903.64,"Terms":"Net30","Discount":35,"Comments":"This customer is on credit hold.","Fax":"","EmailAddress":""}

Posted by Stefan Drissen on 24-Sep-2014 14:26

Hi Srinivas,

Does the rest expose editor give any user interface clue that you can do this? I only see that there is an input temp-table. I can see this working for the query string parameters, but how do I indicate which temp-table field needs to be mapped in the path parameters?

A quick test with the following .p

@openapi.openedge.export FILE(type="REST", executionMode="single-run", useReturnValue="false", writeDataSetBeforeImage="false").

DEFINE TEMP-TABLE tt NO-UNDO
   FIELD adm_nr   AS INTEGER
   FIELD debtor   AS INTEGER
   FIELD country  AS CHARACTER
INDEX ttix IS UNIQUE PRIMARY adm_nr debtor.

@openapi.openedge.export(type="REST", useReturnValue="false", writeDataSetBeforeImage="false").
PROCEDURE lala:
   DEFINE INPUT PARAMETER TABLE FOR tt.

   FIND FIRST tt NO-ERROR.

   IF AVAILABLE tt THEN
      MESSAGE tt.adm_nr tt.debtor.
   ELSE
      MESSAGE "tt not available".

END PROCEDURE.


With path mapping defined as:

tt/{adm_nr}/{debtor}

With both path parameters mapped to interface parameter 'tt' results in errors in the AppServer log:

Error parsing JSON: unexpected token: eof. (15360) 
Error attempting to run 'lala tt.p'. JSON value of ProDataset or temp-table parameter is invalid or empty. (16992)
An incomplete client request. (8020)

Posted by Srinivas Munigala on 25-Sep-2014 01:15

You can't map each field of the temp-table to each parameter. Here, your input temp-table (i.e. tt) is an object and it can be mapped to a single path or query parameter (as shown in attachment).
And you need to pass the field values in json format as I mentioned earlier.
 

 
 
[collapse]
From: Stefan Drissen [mailto:bounce-14941@community.progress.com]
Sent: Thursday, September 25, 2014 12:57 AM
To: TU.OE.Development@community.progress.com
Subject: RE: [Technical Users - OE Development] REST input to temp-table?
 
Reply by Stefan Drissen

Hi Srinivas,

Does the rest expose editor give any user interface clue that you can do this? I only see that there is an input temp-table. I can see this working for the query string parameters, but how do I indicate which temp-table field needs to be mapped in the path parameters?

A quick test with the following .p

@openapi.openedge.export FILE(type="REST", executionMode="single-run", useReturnValue="false", writeDataSetBeforeImage="false").
 
DEFINE TEMP-TABLE tt NO-UNDO
   FIELD adm_nr   AS INTEGER
   FIELD debtor   AS INTEGER
   FIELD country  AS CHARACTER
INDEX ttix IS UNIQUE PRIMARY adm_nr debtor.
 
@openapi.openedge.export(type="REST", useReturnValue="false", writeDataSetBeforeImage="false").
PROCEDURE lala:
   DEFINE INPUT PARAMETER TABLE FOR tt.
 
   FIND FIRST tt NO-ERROR.
 
   IF AVAILABLE tt THEN
      MESSAGE tt.adm_nr tt.debtor.
   ELSE
      MESSAGE "tt not available".
 
END PROCEDURE.


With path mapping defined as:

tt/{adm_nr}/{debtor}

With both path parameters mapped to interface parameter 'tt' results in errors in the AppServer log:

Error parsing JSON: unexpected token: eof. (15360) 
Error attempting to run 'lala tt.p'. JSON value of ProDataset or temp-table parameter is invalid or empty. (16992)
An incomplete client request. (8020)
Stop receiving emails on this subject.

Flag this post as spam/abuse.

[/collapse]

Posted by Stefan Drissen on 25-Sep-2014 02:16

I understand the query part.

How should the path be mapped?

From what I see so far, using a temp-table / dataset as input from the path / query is not going to give a usable solution.

Maybe an example based on tt above will help. I have defined the following rest resources:

/lala/{adm_nr}/{debtor} -> /lala/621/1010

/lala/{adm_nr} -> /lala/621?country=NL

/lala -> /lala?country=NL

The first allows me to get one entity using its key.

The second and third allow me to search entities using a partial key (adm_nr = company) and query parameters

The only sensible way I see of achieving this at the moment is to define all input temp-table fields as input parameters.

Is this correct?

Posted by Srinivas Munigala on 25-Sep-2014 04:48

Even for PATH parameter, you need to map tt object to single path parameter (as shown in attached file).
 
And your request would be as below:
 
http://localhost:8980/ttQueryPath/rest/ttQueryPathService/test/{"Country":"India","Name":"OpenEdge","Address":"iLabs","Address2":"","City":"Hyd","State":"AP","PostalCode":"400005","Contact":"Gloria Shepley","Phone":"(617) 450-0086","SalesRep":"HXM","CreditLimit":66700.00,"Balance":903.64,"Terms":"Net30","Discount":35,"Comments":"This customer is on credit hold.","Fax":"","EmailAddress":""}
 
But, I would suggest to map temp-table / dataset like objects to body instead of path / query parameter as it would be very easy to send json format data in body rather path / query.
 

 
[collapse]
From: Stefan Drissen [mailto:bounce-14941@community.progress.com]
Sent: Thursday, September 25, 2014 12:47 PM
To: TU.OE.Development@community.progress.com
Subject: RE: [Technical Users - OE Development] REST input to temp-table?
 
Reply by Stefan Drissen

I understand the query part.

How should the path be mapped?

From what I see so far, using a temp-table / dataset as input from the path / query is not going to give a usable solution.

Maybe an example based on tt above will help. I have defined the following rest resources:

/lala/{adm_nr}/{debtor} -> /lala/621/1010

/lala/{adm_nr} -> /lala/621?country=NL

/lala -> /lala?country=NL

The first allows me to get one entity using its key.

The second and third allow me to search entities using a partial key (adm_nr = company) and query parameters

The only sensible way I see of achieving this at the moment is to define all input temp-table fields as input parameters.

Is this correct?

Stop receiving emails on this subject.

Flag this post as spam/abuse.

[/collapse]

Posted by Stefan Drissen on 25-Sep-2014 05:46

Thanks - that clears it up - putting a json string in the URL does not look like the way to go.

For the data returned / updates the json will definitely go in the body.

For the GET actions I see no sensible alternative to defining input simple variables as input parameters.

Posted by RWEBSTER on 26-Sep-2014 03:30

"But, I would suggest to map temp-table / dataset like objects to body instead of path / query parameter as it would be very easy to send json format data in body rather path / query."

I agree this is nicer, but I can't work out how I'd need to annotate the ABL procedure/method to pull the 'body' of a REST call in as an input parameter (specifically a temp-table. I've created loads of GET/Read methods so I understand how to pull in single parameters from the URL/Path, and could probably get a temp-table to work in the same way, but I'd much rather use the body for this.

Sidenote: I've search pretty hard and found very little meaningful documentation on this, am I just looking in the wrong place?

Posted by jmls on 26-Sep-2014 03:37

make the body a json object, and read-json on the temp-table ?

On 26 September 2014 09:30, RWEBSTER
wrote:
> RE: REST input to temp-table?
> Reply by RWEBSTER
>
> "But, I would suggest to map temp-table / dataset like objects to body
> instead of path / query parameter as it would be very easy to send json
> format data in body rather path / query."
>
> I agree this is nicer, but I can't work out how I'd need to annotate the ABL
> procedure/method to pull the 'body' of a REST call in as an input parameter
> (specifically a temp-table. I've created loads of GET/Read methods so I
> understand how to pull in single parameters from the URL/Path, and could
> probably get a temp-table to work in the same way, but I'd much rather use
> the body for this.
>
> Sidenote: I've search pretty hard and found very little meaningful
> documentation on this, am I just looking in the wrong place?
>
> Stop receiving emails on this subject.
>
> Flag this post as spam/abuse.



--
Julian Lyndon-Smith
IT Director,
dot.r
http://www.dotr.com

Posted by RWEBSTER on 26-Sep-2014 03:45

But doesn't the REST adapter do that for me? I mean if I have an output table, it's automagically transcoded into JSON for me. Is the reverse not true?

Posted by jmls on 26-Sep-2014 03:56

oh, you're doing things the *complicated* way ?

:)

you may be needing the jdso things - they are an extra cost - but I
stick to the very basic webspeed system. No need for tomcat or
anything like that.

On 26 September 2014 09:45, RWEBSTER
wrote:
> RE: REST input to temp-table?
> Reply by RWEBSTER
>
> But doesn't the REST adapter do that for me? I mean if I have an output
> table, it's automagically transcoded into JSON for me. Is the reverse not
> true?
>
> Stop receiving emails on this subject.
>
> Flag this post as spam/abuse.



--
Julian Lyndon-Smith
IT Director,
dot.r
http://www.dotr.com

Posted by Michael Jacobs on 26-Sep-2014 05:38

A complex object, such as a temp-table or Prodataset must always be transported in the body of a request or response.   The object may be a single JSON object occupying the entire body, or optionally a parameter in a body's multi-parameter JSON object (depending on how you used the mapping utility)

The REST adapter and AppServer work together to take JSON in and deliver it to an AppServer procedure's input temp-table/dataset parameter and take an output temp-table/dataset and produce JSON back to the REST client.

Posted by RWEBSTER on 26-Sep-2014 06:49

Thanks Michael, with that in mind:

The business entity wizard in PDSOE built a method that looks like the below code, my question is: Do I need to intervene the annotation part here or do I need to just deal with the ABL bit. I only ask, because try as I might I can't get any data into my temptable.



@openapi.openedge.export(type="REST", useReturnValue="false", writeDataSetBeforeImage="false"). @progress.service.resourceMapping(type="REST", operation="update", URI="", alias="", mediaType="application/json").
METHOD PUBLIC VOID UpdateTenant(INPUT-OUTPUT TABLE TT_Tenant):
for each TT_Tenant: /*Code here*/ end. END METHOD.

Posted by Bill Wood on 26-Sep-2014 07:02

If you were using the Business Entity Wizard, you can check the JSDO Catalog file that was created (in WebContent directory).

This has the HTTP-REQUEST methods that were set.    You can use the PDSOE tooling to change the VERBs, but the default is for this to be a PUT.   (Have you been doing POST?)
  {
       "name": "UpdateTenant",
       "path": "\/UpdateTenant",
       "type": "invoke",
       "verb": "put",
       "params": [{
            "name": "ttTenant",
            "type": "REQUEST_BODY"
  }
 

Posted by RWEBSTER on 26-Sep-2014 07:24

Hi Bill, yes, I've been using PUT.

The catalog file's there but the path element is not populated in the same way as your example (although I'd expect this as my annotations don't have a path specified):

{

                       "path": "",

                       "type": "update",

                       "verb": "put",

                       "params": [{

                           "name": "TT_Tenant",

                           "type": "REQUEST_BODY"

                       }]

Is that the issue?

Posted by Bill Wood on 26-Sep-2014 07:35

You might not match mine exactly.   The Catalog does allow for different patterns in how path is matched.   You may have the path ‘above’ in the resource definition…   the following truncated catalog JSON file is probably more similar to yours.  But it does look like you have a mapping of Request Body to the TT_Tenant parameter, and it should be on a PUT – my next test would be to use REST debugging or Fiddler to just verify that the Content seems to match. 
 
        "resources": [
            {
                "name": "WarehouseTbl",
                "path": "\/Warehouse",
                <snip>
               "operations": [
                    <snip>
                    {
                        "path": "",
                        "useBeforeImage": false,
                        "type": "update",
                        "verb": "put",
                        "params": [{
                            "name": "dsWarehouse",
                            "type": "REQUEST_BODY"
                        }]
                    <snip>
 

Posted by Shelley Chase on 26-Sep-2014 09:05

The request and response messages will automatically be put into the body and then mapped back from the body. It depends on field names to do the automatic mapping.

Are you having trouble getting the data to the client or from the client to the server?

Posted by RWEBSTER on 29-Sep-2014 03:54

I *was* having issues getting data to the server, but at Bill's recommendation I tried using Fiddler. Turns out my old REST test client was doing something odd with the body.

Thanks all!

This thread is closed