1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

  2. Anuncie Aqui ! Entre em contato fdantas@4each.com.br

Progress REST PUT in classic server returns error

Discussão em 'StackOverflow' iniciado por fdantas, Fevereiro 1, 2019.

  1. fdantas

    fdantas Administrator Moderador

    I have a test table called Cities. Creation script is as follows:

    ADD TABLE "Cities"
    AREA "Schema Area"
    LABEL "Cities"
    DUMP-NAME "Cities"

    ADD FIELD "ID" OF "Cities" AS integer
    DESCRIPTION "ID"
    INITIAL 0
    LABEL "ID"
    COLUMN-LABEL "ID"
    ORDER 10

    ADD FIELD "City" OF "Cities" AS character
    DESCRIPTION "City name"
    FORMAT "x(30)"
    INITIAL ""
    LABEL "Cities"
    MAX-WIDTH 30
    COLUMN-LABEL "Cities"
    ORDER 20

    ADD INDEX "IxID" ON "Cities"
    AREA "Schema Area"
    UNIQUE
    PRIMARY
    INDEX-FIELD "ID" ASCENDING
    .
    PSC
    cpstream=1250
    .
    0002253205


    I have added one record to this table:

    create Cities.
    assign
    Cities.ID = 1
    Cities.City = "Boston".


    FOR EACH routine shows proper result with one record.

    I have created some REST project with classic server settings for learning and testing purposes. All servers and configurations are standard as installator configured them. I have added some procedures to AppServer folder (file: test.p) and created temp-table within it. Full procedure code:

    BLOCK-LEVEL ON ERROR UNDO, THROW.

    DEFINE TEMP-TABLE ttCities LIKE Cities.

    @openapi.openedge.export(type="REST", useReturnValue="false", writeDataSetBeforeImage="false").
    PROCEDURE readCities:

    DEFINE OUTPUT PARAMETER TABLE FOR ttCities.

    FOR EACH Cities NO-LOCK:
    CREATE ttCities.
    BUFFER-COPY Cities TO ttCities.
    END.

    END PROCEDURE.

    @openapi.openedge.export(type="REST", useReturnValue="false", writeDataSetBeforeImage="false").
    PROCEDURE putCities:

    DEFINE INPUT-OUTPUT PARAMETER TABLE FOR ttCities.

    END PROCEDURE.


    Procedure compiles well, annotations are added by Define Service Interface functionality in OpenEdge. In Defined Services node I have created mappings for parameters (I will omit readCities because it works well) for putCities and PUT verb:

    1. Resources: /PutCities
    2. Verb Association: Verb='PUT' -> test..putCities
    3. Mapping Definitions for Input: parameter ttCities is connected to request HTTP Message -> Body section directly (not to body parameter)
    4. Mapping Definitions for Output: response ttCities is connected to Interface Parameters -> ttCities

    My client code is very basic - taken from some Progress KB article and project has OpenEdge.Net.pl libraries included in PROPATH:

    BLOCK-LEVEL ON ERROR UNDO, THROW.

    USING Progress.Json.ObjectModel.JsonObject.
    USING Progress.Json.ObjectModel.*.
    USING Progress.Json.ObjectModel.ObjectModelParser.
    USING Progress.Lang.Object.
    USING OpenEdge.Core.WidgetHandle.
    USING OpenEdge.Core.String.
    USING OpenEdge.Net.HTTP.IHttpRequest.
    USING OpenEdge.Net.HTTP.IHttpResponse.
    USING OpenEdge.Net.HTTP.ClientBuilder.
    USING OpenEdge.Net.HTTP.RequestBuilder.
    DEFINE VARIABLE oRequest AS IHttpRequest NO-UNDO.
    DEFINE VARIABLE oResponse AS IHttpResponse NO-UNDO.
    DEFINE VARIABLE oEntity AS Object NO-UNDO.
    DEFINE VARIABLE lcHTML AS LONGCHAR NO-UNDO.
    DEFINE VARIABLE hXmlDoc AS HANDLE NO-UNDO.
    DEFINE VARIABLE hCities AS HANDLE NO-UNDO.
    DEFINE VARIABLE oJson AS JsonObject NO-UNDO.
    DEFINE VARIABLE lReturnValue AS LOGICAL NO-UNDO.

    DEFINE TEMP-TABLE ttCities LIKE Cities.

    hCities = TEMP-TABLE ttCities:HANDLE.

    create ttCities.
    assign
    ttCities.ID = 1
    ttCities.City = "Boston".

    oJson = NEW JsonObject().
    lReturnValue = oJson:Read(hCities).

    oRequest = RequestBuilder:put('http://127.0.0.1:8980/REST6/rest/REST6/PutCities', oJson):Request.
    oResponse = ClientBuilder:Build():Client:Execute(oRequest).

    MESSAGE oResponse:StatusCode oResponse:StatusReason VIEW-AS ALERT-BOX.

    /* some other code to parse response */


    This code compiles well, but calling it give this error: Cities already exists with ID 1.

    I suppose that procedure is called on the server but can't update DB record because of this error. As far as I know calling PUT method should perform update on record - not creating new one. In addition changing ttCities.ID to value 2 creates new record.

    So my question is simple: how to handle with this? Should I write my own custom logic in putCities procedure?

    Any help will be appreciated.

    Continue reading...

Compartilhe esta Página