How to call external API from RPG?

Approaches in integration with external APIs:

Directly to external API

The following RPG procedures can be used to handle external API call:

You can use extApi() where the first mandatory parameter is API method name to complete the request or one of its equivalents (extApiGet(), extApiPost(), extApiPut() or extApiDelete()) for given HTTP method.

All the procedures contain url parameter which is also mandatory.

Other parameters (httpHeader and requestMsg) are optional.

httpHeader

It’s possible to specify HTTP header for given request in XML format. See Foundational HTTP functions at IBM Knowledge Center for a description of the header content.

There are some predefined constants in Aperio copy book which can be used to indicate that request body has content of given type.

Media type of the request bodyAperio copy book constant nameValue
application/xml (usually for SOAP)EXTAPI_HTTP_HEADER_XML<httpHeader><header name="content-type" value="application/xml" /></httpHeader>
application/json (usually for REST)EXTAPI_HTTP_HEADER_JSON<httpHeader><header name="content-type" value="application/json" /></httpHeader>
text/plainEXTAPI_HTTP_HEADER_TEXT<httpHeader><header name="content-type" value="text/plain" /></httpHeader>
requestMsg

Format and structure (e.g. XML or JSON) of request body depends on web service design and is specific to an external API.

response

All the procedures return response message data structure (see data structure description here). Format and structure of response.body depends on web service design and is specific to an external API.

See External API Procedures chapter for detailed information about parameters and return value from the procedures.

Below there are a couple of examples.

Example 1

SOAP API based on test environment for VIES VAT number validation service via POST HTTP method

      ****************************************************************
      * copybooks
      ****************************************************************

      /COPY QASWCPYPRC,IAFS0001                  API Framework

     D url             s           2048A   varying
     D httpHeader      s          10240A   varying
     D requestMsg      s          65535A   varying      
     D response        DS                  likeds(responseMsg_t)

      /free

       url = 'http://ec.europa.eu/taxation_customs' +
         '/vies/services/checkVatTestService';

       httpHeader = '<httpHeader>' +
            '<header name="content-type" value="application/xml"/>' +
         '</httpHeader>';

       requestMsg =  '<s11:Envelope ' +
           'xmlns:s11=''http://schemas.xmlsoap.org/soap/envelope/''>' +
           '<s11:Body>' +
             '<tns1:checkVat xmlns:tns1=' +
               '''urn:ec.europa.eu:taxud:vies:services:checkVat:types''>' +
               '<tns1:countryCode>PL</tns1:countryCode>' +
               '<tns1:vatNumber>100</tns1:vatNumber>' +
             '</tns1:checkVat>' +
           '</s11:Body>' +
         '</s11:Envelope>';

       response = extApiPost(url:httpHeader:requestMsg);   

      /end-free

response data structure looks in the following way:

RESPONSE
  RETURNCODE = 0            
  HTTPSTATUSCODE = 200          
  HTTPHEADER = <?xml version="1.0" encoding="UTF-8" ?><httpHeader responseCode="200"><responseMessage>OK</responseMessage><header name="Transfer-Encoding" value="chunked"/><header name="HTTP_RESPONSE_CODE" value="HTTP/1.1 200 OK"/><header name="Server" value="Europa"/><header name="Content-Encoding" value="gzip"/><header name="Connection" value="Keep-Alive"/><header name="Date" value="Thu, 23 Jul 2020 09:14:47 GMT"/><header name="Content-Type" value="text/xml; charset=UTF-8"/></httpHeader>
  BODY = <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><checkVatResponse xmlns="urn:ec.europa.eu:taxud:vies:services:checkVat:types"><countryCode>PL</countryCode><vatNumber>100</vatNumber><requestDate>2020-07-23+02:00</requestDate><valid>true</valid><name>John Doe</name><address>123 Main St, Anytown, UK</address></checkVatResponse></soap:Body></soap:Envelope>

Example 2

REST API based on JSONPlaceholder - fake online REST API for developers via GET HTTP method

      ****************************************************************
      * copybooks
      ****************************************************************
      
      /COPY QASWCPYPRC,IAFS0001                  API Framework

     D url             s           2048A   varying
     D httpHeader      s          10240A   varying
     D requestMsg      s          65535A   varying      
     D response        DS                  likeds(responseMsg_t)

      /free

       url = 'https://jsonplaceholder.typicode.com/posts/1';

       httpHeader = '<httpHeader>' +
         '<header name="content-type" value="application/json" />' +
       '</httpHeader>';

       response = extApiGet(url:httpHeader); 

      /end-free

response data structure looks in the following way:

RESPONSE
  RETURNCODE = 0            
  HTTPSTATUSCODE = 200          
  HTTPHEADER = <?xml version="1.0" encoding="UTF-8" ?><httpHeader responseCode="200"><responseMessage>OK</responseMessage><header name="HTTP_RESPONSE_CODE" value="HTTP/1.1 200 OK"/><header name="Server" value="cloudflare"/><header name="X-Ratelimit-Reset" value="1595489434"/><header name="Etag" value="W/&quot;124-yiKdLzqO5gfBrJFrcdJ8Yq0LGnU&quot;"/><header name="Access-Control-Allow-Credentials" value="true"/><header name="Content-Encoding" value="gzip"/><header name="Set-Cookie" value="__cfduid=d1c301749f8dc5a8f69dfbd9ace2299191595496472; expires=Sat, 22-Aug-20 09:27:52 GMT; path=/; domain=.typicode.com; HttpOnly; SameSite=Lax"/><header name="Age" value="7049"/><header name="cf-request-id" value="041c99395a0000f2108baab200000001"/><header name="X-Powered-By" value="Express"/><header name="Content-Type" value="application/json; charset=utf-8"/><header name="Transfer-Encoding" value="chunked"/><header name="CF-RAY" value="5b745e3bcfeef210-ARN"/><header name="X-Ratelimit-Remaining" value="999"/><header name="X-Content-Type-Options" value="nosniff"/><header name="Connection" value="keep-alive"/><header name="Pragma" value="no-cache"/><header name="Date" value="Thu, 23 Jul 2020 10:16:02 GMT"/><header name="Via" value="1.1 vegur"/><header name="X-Ratelimit-Limit" value="1000"/><header name="CF-Cache-Status" value="HIT"/><header name="Cache-Control" value="max-age=43200"/><header name="Vary" value="Origin, Accept-Encoding"/><header name="Expires" value="-1"/><header name="Expect-CT" value="max-age=604800, report-uri=&quot;https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct&quot;"/></httpHeader>
  BODY = {
  "userId": 1,
  "id": 1,
  "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
  "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
}