Nos premiers tests vont utiliser la fonction HTTPGETCLOB de SYSTOOLS (le client REST par excellence)
Exécution
Temps d'exécution (mesuré par ANZCMDPFR)
Mais, pouvons nous, récupérer de la donnée utile (uniquement les valeurs) ?
SQL possède une fonction JSON_TABLE dans SYSTOOLS, permettant de retrouver une colonne à la fois
**free // paramètre(s) en entrée dcl-pi *n; unclient char(10); END-PI; // variables dcl-s URL varchar(128) inz('http://localhost:10066/web/services/Clients/'); dcl-s wid int(10); dcl-s wref char(10); dcl-s wnom char(15); dcl-s wprenom char(15); dcl-s wdatechar char(10); dcl-s wdatenaissance date; dcl-s wadresse char(50); dcl-s wsatut char(20); URL += %trim(unclient); // += -> variable concaténée avec elle même EXEC SQL select t1.value as id, t2.value as ref, t3.value as nom, t4.value as prenom, t5.value as datenaissance, t6.value as adresse, t7.value as statut into :wid, :wref, :wnom, :wprenom, :wdatechar, :wadresse, :wsatut from table (SYSTOOLS.JSON_TABLE(systools.json2bson( SYSTOOLS.HTTPGETCLOB(:URL, '')) , 'CLIENTRETOUR.ID' , 'i') ) as t1, table (SYSTOOLS.JSON_TABLE(systools.json2bson( SYSTOOLS.HTTPGETCLOB(:URL, '')) , 'CLIENTRETOUR.REFERENCE', 's:10') ) as t2, table (SYSTOOLS.JSON_TABLE(systools.json2bson( SYSTOOLS.HTTPGETCLOB(:URL, '')) , 'CLIENTRETOUR.NOM', 's:15') ) as t3, table (SYSTOOLS.JSON_TABLE(systools.json2bson( SYSTOOLS.HTTPGETCLOB(:URL, '')) , 'CLIENTRETOUR.PRENOM', 's:15') ) as t4, table (SYSTOOLS.JSON_TABLE(systools.json2bson( SYSTOOLS.HTTPGETCLOB(:URL, '')) , 'CLIENTRETOUR.DATENAISSANCE', 's:10') ) as t5, table (SYSTOOLS.JSON_TABLE(systools.json2bson( SYSTOOLS.HTTPGETCLOB(:URL, '')) , 'CLIENTRETOUR.ADRESSE', 's:50') ) as t6, table (SYSTOOLS.JSON_TABLE(systools.json2bson( SYSTOOLS.HTTPGETCLOB(:URL, '')) , 'CLIENTRETOUR.STATUT', 's:20') ) as t7; wdatenaissance = %date(wdatechar); // pour voir dsply (%char(wid) +'-' + wref); dsply (%char(wdatenaissance)); *INLR = *on; |
Temps d'exécution (mesuré par ANZCMDPFR) Le web service est appelé 7 fois !
Et si nous utilisions YAJL? Le projet OpenSource porté sur IBM i, par Scott Klement.
**free ctl-opt BNDDIR('YAJLLIB/YAJL'); /copy YAJLLIB/QRPGLESRC,YAJL_H dcl-pi *n; unclient char(10); END-PI; dcl-s URL varchar(128) inz('http://localhost:10066/web/services/Clients/'); dcl-s resultat char(1024); dcl-s errmsg varchar(500); dcl-s docNode like(yajl_val); dcl-s Node like(yajl_val); dcl-s val like(yajl_val); // dcl-s wid int(10); dcl-s wref char(10); dcl-s wnom char(15); dcl-s wprenom char(15); dcl-s wdatenaissance date; dcl-s wadresse char(50); dcl-s wstatut char(20); URL += %trim(unclient); EXEC SQL VALUES SYSTOOLS.HTTPGETCLOB(:URL , '') into :resultat; docnode = yajl_buf_load_tree(%addr(resultat):%len(%trimr(resultat)):errmsg); node = YAJL_OBJECT_FIND(docNode: 'CLIENTRETOUR'); val = YAJL_OBJECT_FIND(node: 'ID'); wid = YAJL_GET_NUMBER(val); val = YAJL_OBJECT_FIND(node: 'REFERENCE'); wref = YAJL_GET_STRING(val); val = YAJL_OBJECT_FIND(node: 'NOM'); wnom = YAJL_GET_STRING(val); val = YAJL_OBJECT_FIND(node: 'PRENOM'); wprenom = YAJL_GET_STRING(val); val = YAJL_OBJECT_FIND(node: 'DATENAISSANCE'); wdatenaissance = %date(YAJL_GET_STRING(val)); val = YAJL_OBJECT_FIND(node: 'ADRESSE'); wadresse = YAJL_GET_STRING(val); val = YAJL_OBJECT_FIND(node: 'STATUT'); wstatut = YAJL_GET_STRING(val); dsply (%char(wid) +'-' + wref); dsply (%char(wdatenaissance)); *INLR = *on; |
Temps d'exécution (mesuré par ANZCMDPFR)
Enfin, réalisons un dernier essai, directement basé sur les Api AXIS (voir l'article dans DeveloperWorks)
**free ctl-opt BNDDIR('YAJLLIB/YAJL'); /copy YAJLLIB/QRPGLESRC,YAJL_H // pour compiler CRTRPGMOD puis CRTPGM BNDSRVPGM((QSYSDIR/QAXIS10CC)) // ******************************************************************** dcl-pi *N; unclient char(10); END-PI; /COPY /QIBM/ProdData/OS/WebServices/V1/client/include/Axis.rpgleinc DCL-S rc INT(10); DCL-S tHandle POINTER; DCL-S uri CHAR(200); DCL-S response CHAR(32768); DCL-S request CHAR(32768); DCL-S propBuf CHAR(100); dcl-s URL varchar(128) inz('http://localhost:10066/web/services/Clients/'); dcl-s errmsg varchar(500); dcl-s docNode like(yajl_val); dcl-s Node like(yajl_val); dcl-s val like(yajl_val); // dcl-s wid int(10); dcl-s wref char(10); dcl-s wnom char(15); dcl-s wprenom char(15); dcl-s wdatenaissance date; dcl-s wadresse char(50); dcl-s wstatut char(20); URL += %trim(unclient); // Create HTTP transport handle. tHandle = axiscTransportCreate(url:AXISC_PROTOCOL_HTTP11); if (tHandle = *NULL); DSPLY ('TransportCreate() failed'); return; endif; // méthode GET propBuf = 'GET' + X'00'; axiscTransportSetProperty(tHandle: AXISC_PROPERTY_HTTP_METHOD: %addr(propBuf)); // Exécution, le résultat est placé dans "Response" flushAndReceiveData(); docnode = yajl_buf_load_tree(%addr(response):%len(%trimr(response)):errmsg); node = YAJL_OBJECT_FIND(docNode: 'CLIENTRETOUR'); val = YAJL_OBJECT_FIND(node: 'ID'); wid = YAJL_GET_NUMBER(val); val = YAJL_OBJECT_FIND(node: 'REFERENCE'); wref = YAJL_GET_STRING(val); val = YAJL_OBJECT_FIND(node: 'NOM'); wnom = YAJL_GET_STRING(val); val = YAJL_OBJECT_FIND(node: 'PRENOM'); wprenom = YAJL_GET_STRING(val); val = YAJL_OBJECT_FIND(node: 'DATENAISSANCE'); wdatenaissance = %date(YAJL_GET_STRING(val)); val = YAJL_OBJECT_FIND(node: 'ADRESSE'); wadresse = YAJL_GET_STRING(val); val = YAJL_OBJECT_FIND(node: 'STATUT'); wstatut = YAJL_GET_STRING(val); dsply (%char(wid) +'-' + wref); dsply (%char(wdatenaissance)); // Cleanup handle. axiscTransportDestroy(tHandle); *INLR=*ON; // ========================================= // Flush and Receive data // ========================================= DCL-PROC flushAndReceiveData; dcl-pi *n; end-pi; DCL-S header POINTER; dcl-s Header_data char(256) based(header); DCL-S property CHAR(100); DCL-S bytesRead INT(10) inz(0); clear response; clear header; // Flush data so request is sent rc = axiscTransportFlush(tHandle); if (rc = -1); DSPLY ('TransportFlush()'); return; endif; // Receive data and print out data and response to stdout rc = axiscTransportReceive(tHandle: %ADDR(response): %SIZE(response): 0); if (rc = 0); DSPLY ('No data to read'); else; dow rc > 0 AND bytesRead < %SIZE(response); bytesRead = bytesRead + rc; rc = axiscTransportReceive(tHandle: %ADDR(response)+bytesRead: %SIZE(response)-bytesRead: 0); enddo; endif; if (rc > -1); rc = axiscTransportGetProperty(tHandle: AXISC_PROPERTY_HTTP_STATUS_CODE: %addr(header)); DSPLY ('HTTP status code: ' + %subst(header_data:1:4)); endif; END-PROC; |
Temps d'exécution (mesuré par ANZCMDPFR)
Suite à TR5 (7.2) / TR1 (7.3) testons la nouvelle version de JSON_TABLE (celle de QSYS2)
Avec HTTPGETCLOB
*free URL += %trim(unclient); EXEC SQL select * into :wid, :wref, :wnom, :wprenom, :wdatenaissance, :wadresse, :wstatut from JSON_TABLE( SYSTOOLS.HTTPGETCLOB(:URL, null), '$.client[*]' COLUMNS( dsply (%char(wid) +'-' + wref); dsply (%char(wdatenaissance)); *INLR = *on; |
Temps d'exécution (mesuré par ANZCMDPFR)
Avec les API Axis
**free dcl-pi *n; unclient char(10); END-PI; /INCLUDE /QIBM/ProdData/OS/WebServices/V1/client/include/Axis.rpgleinc DCL-S rc INT(10); DCL-S tHandle POINTER; DCL-S uri CHAR(200); DCL-S response CHAR(32767); DCL-S request CHAR(32768); DCL-S propBuf CHAR(100); dcl-s URL varchar(128) inz('http://as400:10066/web/services/clients/'); dcl-s json_data sqltype(Clob:32767) ; dcl-s wid int(10); dcl-s wref char(10); dcl-s wnom char(15); dcl-s wprenom char(15); dcl-s wdatenaissance date; dcl-s wadresse char(50); dcl-s wstatut char(20); URL += %trim(unclient); // Create HTTP transport handle. tHandle = axiscTransportCreate(url:AXISC_PROTOCOL_HTTP11); if (tHandle = *NULL); DSPLY ('TransportCreate() failed'); return; endif; // méthode GET propBuf = 'GET' + X'00'; axiscTransportSetProperty(tHandle: AXISC_PROPERTY_HTTP_METHOD: %addr(propBuf)); // Exécution flushAndReceiveData(); json_data_data = response; json_data_len = %len(%trimr(response)); EXEC SQL select * into :wid, :wref, :wnom, :wprenom, :wdatenaissance, :wadresse, :wstatut from JSON_TABLE(:json_data, '$.client[*]' COLUMNS( ID integer PATH '$.id', reference VARCHAR(25) PATH '$.reference', NOM VARCHAR(25) PATH '$.nom', prenom VARCHAR(25) PATH '$.prenom', naissance DATE PATH '$.datenaissance', adresse varchar(35) PATH '$.adresse', statut CHAR(12) PATH '$.statut' )) AS X; dsply (%char(wid) +'-' + wref); dsply (%char(wdatenaissance)); // Cleanup handle. axiscTransportDestroy(tHandle); *INLR=*ON; // ========================================= // Flush and Receive data // ========================================= DCL-PROC flushAndReceiveData; dcl-pi *n; end-pi; DCL-S header POINTER; dcl-s Header_data char(256) based(header); DCL-S property CHAR(100); DCL-S bytesRead INT(10) inz(0); clear response; clear header; // Flush data so request is sent rc = axiscTransportFlush(tHandle); if (rc = -1); DSPLY ('TransportFlush()'); return; endif; // Receive data and print out data and response to stdout rc = axiscTransportReceive(tHandle: %ADDR(response): %SIZE(response): 0); if (rc = 0); DSPLY ('No data to read'); else; dow rc > 0 AND bytesRead < %SIZE(response); bytesRead = bytesRead + rc; rc = axiscTransportReceive(tHandle: %ADDR(response)+bytesRead: %SIZE(response)-bytesRead: 0); enddo; endif; if (rc > -1); rc = axiscTransportGetProperty(tHandle: AXISC_PROPERTY_HTTP_STATUS_CODE: %addr(header)); DSPLY ('HTTP status code: ' + %subst(header_data:1:4)); endif; END-PROC flushAndReceiveData; |
Temps d'exécution (mesuré par ANZCMDPFR)