Klient HTTP ABL

W całym cyklu artykułów kilkakrotnie pisałem o tworzeniu serwisów generujących dane do tzw. endpoint a także o korzystaniu z tych danych do generowania prostego interfejsu użytkownika.

Żeby nie być gołosłownym przypomnę, że dane takie można wygenerować np. do formatu JSON za pomocą wizardów w OE Develeopr Studio dla serwisów rest
1) poprzez warstwę transportową REST
2) lub warstwę transportową WEB.

Wybierając jedną z powyższych metod tworzymy nowy projekt dla wybranej warstwy transportowej, generujący dane do pliku .cls (tutaj plik customer.cls).

Klasa ta ma metody do manipulacji dla danych, które odpowiadają czasownikom HTTP (Read -> GET, Update -> PUT, Create -> POST, Delete -> DELETE).

Dane dostarczane przez serwis możemy testować przy pomocy np. darmowych rozwiązań jak Chrome Advanced REST client czy Postman. Z pierwszego rozwiązania korzystałem już wcześniej tutaj, a z Postmana w niniejszym artykule. Jest to bardzo intuicyjne, czytelne narzędzie zawierające wszystko co możemy potrzebować przy testowaniu żądań HTTP (patrz poniżej).

Jeśli chodzi o drugą stronę, czyli o klienta czytającego wystawione dane, możemy skorzystać z różnych technologii dostępnych na rynku. Ja pokazałem przykład ze zwykłym JavaScriptem tutaj.

W OE 12 możemy zbudować w programie własnego klienta HTTP, czym zajmiemy się teraz.
W tym celu będziemy korzystać z biblioteki OpenEdge.Net, która udostępnia klasy i interfejsy umożliwiające tworzenie żądań HTTP oraz przetwarzanie odpowiedzi HTTP w języku ABL.

USING OpenEdge.Core.Collections.IStringStringMap FROM PROPATH.
USING OpenEdge.Net.HTTP.ClientBuilder FROM PROPATH.
USING OpenEdge.Net.HTTP.Credentials FROM PROPATH.
USING OpenEdge.Net.HTTP.IHttpClient FROM PROPATH.
USING OpenEdge.Net.HTTP.IHttpRequest FROM PROPATH.
USING OpenEdge.Net.HTTP.IHttpResponse FROM PROPATH.
USING OpenEdge.Net.HTTP.RequestBuilder FROM PROPATH.
USING OpenEdge.Net.URI FROM PROPATH.
USING Progress.Json.ObjectModel.JsonObject FROM PROPATH.

/* ***************************  Main Block  *************************** */
DEFINE VARIABLE oClient AS IHttpClient NO-UNDO.
DEFINE VARIABLE oURI AS URI NO-UNDO.
DEFINE VARIABLE oRequest AS IHttpRequest NO-UNDO.
DEFINE VARIABLE oForm AS IStringStringMap NO-UNDO.
DEFINE VARIABLE OResponse AS IHttpResponse NO-UNDO.
DEFINE VARIABLE oJsonObject AS JsonObject NO-UNDO.
DEFINE VARIABLE JsonString AS LONGCHAR NO-UNDO.
DEFINE VARIABLE oCredentials AS Credentials NO-UNDO.

// Build the client
oClient = ClientBuilder:Build():Client.
oURI = URI:Parse("http://localhost:8810/myrest/rest/myrestService/customer?filter=CustNum=3000").

// Build the request
oRequest = RequestBuilder:GET(oURI):Request.

// Execute the request
oResponse = oClient:Execute(oRequest).
 
//Process the response
IF oResponse:StatusCode <> 200 THEN
    MESSAGE "Request Error " + STRING(OResponse:StatusCode) VIEW-AS ALERT-BOX.
ELSE DO:
    oJsonObject = CAST(oResponse:Entity, JsonObject).
    oJsonObject:Write(JsonString, true).
    MESSAGE STRING(JsonString) VIEW-AS ALERT-BOX.
    END.

Kod procedury jest dość prosty. Najpierw budowany jest klient HTTP, potem żądanie, a na koniec żądanie jest wykonywane. Musimy podać tu tylko URI do zdefiniowanego wcześniej serwisu. Instrukcja MESSAGE zwraca nam pobrany JSON, zapamiętajmy nazwy obiektów.

Jeśli chcemy korzystać z poszczególnych danych w programie (no bo po co czytaliśmy JSON?), to wygodnie wczytać je do tabeli tymczasowej w ProDataSecie. Nazwy obiektów muszą być takie jak w JSON, czyli: ttCustomer, dsCustomer. Dodajemy poniższy kod i testujemy.

    DEFINE VARIABLE lRetOK      AS LOGICAL   NO-UNDO.
    DEFINE VARIABLE hdsCust     AS HANDLE    NO-UNDO.
    
    DEFINE TEMP-TABLE ttCustomer LIKE Customer.
    DEFINE DATASET dsCustomer FOR ttCustomer.
    
    hdsCust = DATASET dsCustomer:HANDLE.
    lRetOK = hdsCust:READ-JSON("LONGCHAR", JsonString, "EMPTY").
    FIND FIRST ttCustomer.
    DISPLAY custnum NAME.


Powrócę wkrótce do klienta HTTP z tematem związanym z uwierzytelnianiem. Zachęcam do testów!