REST input to temp-table? - Forum - OpenEdge Development - Progress Community
 Forum

REST input to temp-table?

This question is answered

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?

Verified Answer
  • 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.
     

     
    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.

All Replies
  • 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":""}

  • 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)
  • 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.
     

     
     
    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.

  • 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?

  • 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.
     

     
    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.

  • 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.

  • "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?

  • 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
  • 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?

  • 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
  • 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.

  • 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.

  • 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"
      }
     
  • 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?

  • 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>