Openedge Abl Develop HTTP Clients
Openedge Abl Develop HTTP Clients
ABL
Copyright
© 2020 Progress Software Corporation and/or its subsidiaries or affiliates. All rights reserved.
®
These materials and all Progress software products are copyrighted and all rights are reserved by Progress
Software Corporation. The information in these materials is subject to change without notice, and Progress
Software Corporation assumes no responsibility for any errors that may appear therein. The references in
these materials to specific platforms supported are subject to change.
Corticon, DataDirect (and design), DataDirect Cloud, DataDirect Connect, DataDirect Connect64, DataDirect
XML Converters, DataDirect XQuery, DataRPM, Defrag This, Deliver More Than Expected, Icenium, Ipswitch,
iMacros, Kendo UI, Kinvey, MessageWay, MOVEit, NativeChat, NativeScript, OpenEdge, Powered by Progress,
Progress, Progress Software Developers Network, SequeLink, Sitefinity (and Design), Sitefinity, SpeedScript,
Stylus Studio, TeamPulse, Telerik, Telerik (and Design), Test Studio, WebSpeed, WhatsConfigured,
WhatsConnected, WhatsUp, and WS_FTP are registered trademarks of Progress Software Corporation or one
of its affiliates or subsidiaries in the U.S. and/or other countries. Analytics360, AppServer, BusinessEdge,
DataDirect Autonomous REST Connector, DataDirect Spy, SupportLink, DevCraft, Fiddler, iMail, JustAssembly,
JustDecompile, JustMock, NativeScript Sidekick, OpenAccess, ProDataSet, Progress Results, Progress
Software, ProVision, PSE Pro, SmartBrowser, SmartComponent, SmartDataBrowser, SmartDataObjects,
SmartDataView, SmartDialog, SmartFolder, SmartFrame, SmartObjects, SmartPanel, SmartQuery, SmartViewer,
SmartWindow, and WebClient are trademarks or service marks of Progress Software Corporation and/or its
subsidiaries or affiliates in the U.S. and other countries. Java is a registered trademark of Oracle and/or its
affiliates. Any other marks contained herein may be trademarks of their respective owners.
March 2020
Updated: 2020/09/10
Table of Contents
Purpose
This document provides an overview of the tasks that are required to develop an HTTP client in ABL. It describes
how to use some of the key classes and interfaces in the OpenEdge.Net procedure library to make REST
calls over HTTP.
Audience
This document is intended for ABL developers who want to develop an HTTP client application in ABL. To be
able to benefit from this document, you need to be familiar with object oriented programming in ABL.
Organization
This document comprises three major parts:
• Build an HTTP request on page 11, which describes how to build an HTTP request object, with a request
body, headers, and other properties such as the HTTP method and Authentication.
• Execute an HTTP request on page 23, which describes how to execute the HTTP request and configure
TLS settings.
• Process an HTTP response on page 28, which describes how to handle response messages returned by
the REST API or server.
Documentation conventions
See Documentation Conventions for an explanation of the terminology, format, and typographical conventions
used throughout the OpenEdge content library.
The OpenEdge.Net library supports all HTTP methods and all content types. It also supports HTTP
authentication, Transport Layer Security (TLS) communication, the use of HTTP proxies, and the development
of stateful HTTP clients using cookies.
Note: The following topics cover the key features of the OpenEdge.Net procedure library. See the OpenEdge
API reference documentation to learn about all the available classes, methods, and interfaces. Additional code
samples can be found on GitHub.
Main steps
Perform the following steps to develop an ABL HTTP client:
1. Build an HTTP request
Use the OpenEdge.Net.HTTP.RequestBuilder class to create a request object that implements the
OpenEdge.Net.HTTP.IHttpRequest interface. You must specify an HTTP method (GET, PUT, POST,
etc) and a URI. For example:
oURI =
URI:Parse("http://oemobiledemo.progress.com/OEMobileDemoServices/rest/CustomerService/Customer?filter=CustNum=1").
oRequest = RequestBuilder:GET(oURI):Request.
You can optionally add HTTP headers and a request body. To learn more about these and other options,
see Build an HTTP request on page 11.
oClient = ClientBuilder:Build():Client.
oResponse = oClient:Execute(oRequest).
You can also use the client object to perform other tasks such as setting cookies or specifying TLS properties.
To learn more about these tasks, see Execute an HTTP request on page 23.
Example
This example sends a GET request and processes a JSON response:
USING OpenEdge.Net.HTTP.*.
USING OpenEdge.Net.URI.
USING Progress.Json.ObjectModel.*.
//Build a request
oURI =
URI:Parse("http://oemobiledemo.progress.com/OEMobileDemoServices/rest/CustomerService/Customer?filter=CustNum=1").
oRequest = RequestBuilder:GET(oURI):Request.
//Execute a request
oClient = ClientBuilder:Build():Client.
oResponse = oClient:Execute(oRequest).
Additional resources
• Samples on GitHub
• OpenEdge.Net API Reference
• A blank line that separates the header section from the request body.
• A request body that consists of the payload or data that is to be sent to the server.
oURI =
URI:Parse("http://oemobiledemo.progress.com/OEMobileDemoServices/rest/CustomerService/Customer?filter=CustNum=1").
oRequest = RequestBuilder:GET(oURI):Request.
To build requests that use other HTTP verbs, replace GET with the appropriate verb name, as shown in the
following example.
Another way to build an HTTP request is to use the Build() method, where you pass the HTTP verb as a
parameter.
Based on your requirements, you may also need to perform the following tasks:
• Add query and path parameters to the URI on page 13
• Add HTTP request headers on page 15
• Add an HTTP request body on page 15
• Use HTTP authentication on page 21
oRequest = RequestBuilder
:GET(<URI>)
/* Other options include PUT | POST | DELETE | HEAD | PATCH | OPTIONS | TRACE */
:AddHeader(<HttpHeader>)
:HttpVersion("HTTP/1.1")
:WithData(Progress.Lang.Object)
:ContentType(<char>)
:AuthCallback(<callback object> | <callback procedure>)
:UsingBasicAuthentication(<Credentials>)
/* Other options include UsingDigestAuthentication(<Credentials>) |
UsingCredentials(<Credentials>) */
:ViaProxy(<url>)
:WithTransferEncoding(<encoding>)
:Request.
Note: Currently, the OpenEdge.Net library supports only HTTP 1.1, so if you need to use the HttpVersion()
method, you should pass the string "HTTP/1.1"—HttpVersion("HTTP/1.1").
USING OpenEdge.Net.HTTP.*.
USING OpenEdge.Net.URI.
oClient = ClientBuilder:Build():Client.
oURI = new URI('http', 'oemobiledemo.progress.com').
To append additional path segments to the base URI (which you need to do for most REST API endpoints),
use the Path property:
Alternatively, you can use the Parse() method to turn a string into a URI object:
oURI =
URI:Parse('http://oemobiledemo.progress.com/OEMobileDemoServices/rest/CustomerService/Customer').
http://oemobiledemo.progress.com/OEMobileDemoServices/rest/CustomerService/Customer?filter=Country='Finland'
The ? in the URI path indicates that a query string follows. Multiple queries can be passed using the & separator.
For example, to select customers from Finland, who have 'DKP' as their sales representative, you would need
a URI like this:
http://oemobiledemo.progress.com/OEMobileDemoServices/rest/CustomerService/Customer?filter=Country='Finland'&SalesRep='DKP'
To add a query to your URI object, choose from one of the following options:
• Add a query string (using the AddQueryString() method). Use this option if you have a string comprising
all the query parameters.
oURI:AddQueryString("filter=Country='Finland'", false).
The AddQueryString() method takes two parameters—the query string, which is a character string, and
1
a logical (true or false) value that indicates whether the query string should be URL decoded .
• Add one or more queries by calling AddQuery() for each parameter. Use this option if you have many
queries, some of which are populated by variable values.
oURI:AddQuery("filter", "'Country=Finland'").
oURI:AddQuery("SalesRep", "DKP").
http://oemobiledemo.progress.com/OEMobileDemoServices/rest/CustomerService/Customer/1
1
URLs are encoded as per the IETF specification. URL decoding replaces '%' escape characters in the URL, if any exist.
To set an Accept header that specifies the content type to be returned by the server, select from the following
methods:
String requests
To add a plain string message, create a string and pass the string as the request body.
USING OpenEdge.Net.HTTP.*.
USING OpenEdge.Net.URI.
USING Progress.Json.ObjectModel.*.
//Build a request
oURI = URI:Parse("http://httpbin.org/post").
oRequestBody = new OpenEdge.Core.String("This is a test string").
oRequest = RequestBuilder:POST(oURI, oRequestBody):Request.
//Execute a request
oClient = ClientBuilder:Build():Client.
oResponse = oClient:Execute(oRequest).
JSON requests
To add a JSON message, create a JSON object and pass the object as the request body.
USING OpenEdge.Net.HTTP.*.
USING OpenEdge.Net.URI.
USING Progress.Json.ObjectModel.*.
//Build a request
oURI = URI:Parse("http://httpbin.org/post").
oRequestBody = new JsonObject().
oRequestBody:Add("CustNum", "200").
oRequestBody:Add("Name", "Excellent Sports Apparel").
oRequest = RequestBuilder:POST(oURI, oRequestBody):Request.
//Execute a request
oClient = ClientBuilder:Build():Client.
oResponse = oClient:Execute(oRequest).
oRequest = RequestBuilder:POST(oURI):AddJsonData(oRequestBody):Request.
XML requests
To add an XML message, create an XML document, save it to a MEMPTR variable, and then pass it as an
OpenEdge.Core.Memptr object. The following example loads XML content from a file:
//Build a request
oURI = URI:Parse("http://httpbin.org/post").
CREATE X-DOCUMENT hXmlDoc.
hXmlDoc:LOAD("FILE", "C:/Samples/sample_xml_doc.xml", FALSE).
hXmlDoc:SAVE('MEMPTR', mData).
oDocument = new Memptr(mData).
oRequest = RequestBuilder:POST(oURI, oDocument):Request.
You can also create the XML document in your ABL program. For example:
//Build a request
oURI = URI:Parse("http://httpbin.org/post").
oRequest = RequestBuilder:POST(oURI, oDocument):Request.
USING OpenEdge.Net.HTTP.*.
USING OpenEdge.Net.URI.
USING Progress.Json.ObjectModel.*.
USING OpenEdge.Core.Memptr FROM PROPATH.
//Build a request
oURI = URI:Parse("http://httpbin.org/post").
COPY-LOB FROM FILE "C:/Samples/smile.png" TO mData.
oPic = new Memptr(mData).
oRequest = RequestBuilder:POST(oURI):WithData(oPic):Request.
//Execute a request
oClient = ClientBuilder:Build():Client.
oResponse = oClient:Execute(oRequest).
ELSE
oJsonObject = CAST(oResponse:Entity, JsonObject).
oJsonObject:Write(JsonString, true).
MESSAGE string(JsonString).
USING OpenEdge.Net.HTTP.*.
USING OpenEdge.Net.URI.
USING Progress.Json.ObjectModel.*.
//Build a request
oURI = URI:Parse("http://httpbin.org/post").
oRequest = RequestBuilder:POST(oURI):AddFormData('First Name', 'John'):AddFormData('Last
Name', 'Doe'):Request.
//Execute a request
oClient = ClientBuilder:Build():Client.
oResponse = oClient:Execute(oRequest).
USING Progress.Json.ObjectModel.*.
USING OpenEdge.Net.HTTP.*.
USING OpenEdge.Net.URI.
USING Progress.Json.ObjectModel.*.
USING OpenEdge.Net.MessagePart.
USING OpenEdge.Net.MultipartEntity.
//Build a request
oURI = URI:Parse("http://httpbin.org/post").
oRequest = RequestBuilder:POST(oURI, oEntity):Request.
//Execute a request
oClient = ClientBuilder:Build():Client.
oResponse = oClient:Execute(oRequest).
MESSAGE string(JsonString).
USING OpenEdge.Net.HTTP.Credentials.
httpUrl = "http://localhost:9090/oem/resources".
oRequest = RequestBuilder:Get(httpUrl):UsingBasicAuthentication(oCredentials):Request.
oRequest = RequestBuilder:Get(httpUrl):UsingDigestAuthentication(oCredentials):Request.
Authentication callback
In the authentication callback mechanism, the HTTP client responds to a server's demand for authentication
by invoking an ABL class or procedure that is responsible for providing the required credentials (typically through
a login form or widget presented to a user).
To implement the authentication callback mechanism, use the AuthCallback() method as shown in the
following examples.
Adding Auth Filter Callback as a class
USING OpenEdge.Net.HTTP.Filter.Auth.IAuthFilterEventHandler.
USING OpenEdge.Net.HTTP.Credentials.
oRequest = RequestBuilder:Get('http://localhost:9090/oem/resources')
:AcceptJson()
:AuthCallback(new AuthStatusListener())
:Request.
poEventArgs:Credentials = new
Credentials('domain','admin','4admin').
END METHOD.
END CLASS.
USING OpenEdge.Net.HTTP.AuthenticationRequestEventArgs.
USING OpenEdge.Net.HTTP.Credentials.
oRequest = RequestBuilder:Get('http://localhost:9090/oem/resources')
:AcceptJson()
:AuthCallback(this-procedure)
:Request.
PROCEDURE AuthFilter_HttpCredentialRequestHandler:
DEFINE INPUT PARAMETER poSender as Object.
DEFINE INPUT PARAMETER poEventArgs as AuthenticationRequestEventArgs.
poEventArgs:Credentials = new
Credentials('domain','admin','4admin').
END PROCEDURE.
On-demand authentication
This method is similar to HTTP basic authentication; however, instead of sending credentials preemptively,
the HTTP client sends credentials only when required by the server.To implement this authentication mechanism,
use the UsingCredentials() method as shown in the following example.
oRequest = RequestBuilder:Get('http://localhost:9090/oem/resources')
:AcceptJson()
:UsingCredentials(oCredentials)
:Request.
Authorization header
In addition to using any of the authentication mechanisms listed in this topic, you can use the AddHeader()
method to specify the Authorization header. This is useful in certain situations, such as when you need to
pass OAuth bearer tokens.
lcToken = oJson:GetJsonText("access_token").
cToken = 'Bearer ' + STRING(lcToken).
oRequest = RequestBuilder
:Post('<URL>',oRequestBody)
:AddHeader('Authorization', cToken)
:AcceptJson()
:ContentType('application/json')
:Request.
USING OpenEdge.Net.HTTP.*.
USING OpenEdge.Net.URI.
USING Progress.Json.ObjectModel.*.
//Build a request
oURI =
URI:Parse("http://oemobiledemo.progress.com/OEMobileDemoServices/rest/CustomerService/Customer?filter=CustNum=1").
oRequest = RequestBuilder:GET(oURI):Request.
//Execute a request
oClient = ClientBuilder:Build():Client.
oResponse = oClient:Execute(oRequest).
oClient = ClientBuilder:Build()
:ViaProxy(URI)
:KeepCookies(ICookieJar)
:SetRequestTimeout(DECIMAL)
:SetNumRetries(INTEGER)
:Client.
Use the SetRequestTimeout() method to set a timeout value in seconds for the HTTP connection to be
established. Use the SetNumRetries() method to set the number of attempts at making a connection.
You can also use the client object to:
HTTPS is a combination of HTTP and TLS. When a client application needs to make a request over HTTPS,
it initiates communication by requesting the public key certificate of the server. The certificate is typically signed
by a certificate authority and contains a public key. The client application verifies the certificate and then uses
the public key to encrypt request messages.
An ABL HTTP client can make requests to HTTPS URLs as long as the root certificate of the server is installed
in the OpenEdge certificate store. The HTTP client does not automatically install root certificates.
To retrieve the root certificate for a site, use a browser to navigate to the URL. Modern browsers indicate an
TLS connection with a padlock or some similar icon. This icon is usually clickable and includes a means to
inspect and export the certificates for that site. Make sure you export all of the certificates for the site and import
them into the OpenEdge certificate store.
To learn more about importing certificates, see 'Manage OpenEdge Keys and Certificates' in the Manage
OpenEge Keys and Certificates guide.
Note that while the HTTP client can verify the certificate of a server, it does not support sending client certificates
to the server (also known as two-way or mutual authentication).
USING OpenEdge.Net.HTTP.IHttpClientLibrary.
USING OpenEdge.Net.HTTP.Lib.ClientLibraryBuilder.
oLib = ClientLibraryBuilder:Build():sslVerifyHost(NO):Library.
oHttpClient = ClientBuilder:Build():UsingLibrary(oLib):Client.
If you need to specify TLS ciphers and protocols in your ABL HTTP client, create a custom ClientLibrary
and use the SetSSLProtocols() and SetSSLCiphers() methods as shown in the following example.
USING OpenEdge.Net.HTTP.IHttpClient.
USING OpenEdge.Net.HTTP.IHttpClientLibrary.
USING OpenEdge.Net.HTTP.ClientBuilder.
USING OpenEdge.Net.HTTP.Lib.ClientLibraryBuilder.
// the size and values of the TLS protocols and ciphers depend on the server
EXTENT(cTLSProtocols) = 2.
EXTENT(cSSLCiphers) = 10.
oClient = ClientBuilder:Build()
:UsingLibrary(oLib)
:Client.
For a list of supported ciphers and protocols, see Supported protocols, ciphers, and certificates for Progress
OpenEdge clients and servers in the Learn About Security and Auditing guide.
Each cookie has a domain and a path property that is mapped to a URI. When your HTTP client makes a
request to a URI, all cookies associated with the URI are attached to the request. To enable this behavior,
append the KeepCookies() method when building the HTTP client.
oClient = ClientBuilder:Build():KeepCookies():Client.
Note: You can inspect an individual cookie by casting the cookie to a string (using ToString(),
STRING(oCookie), or MESSAGE oCookie).
USING OpenEdge.Net.HTTP.*.
USING OpenEdge.Net.URI.
USING Progress.Json.ObjectModel.*.
oClient = ClientBuilder:Build():Client.
oURI = new URI('http', 'oemobiledemo.progress.com').
oURI:Path = "/OEMobileDemoServices/rest/CustomerService/Customer".
oURI:AddQueryString("filter=Country='Finland'").
oRequest = RequestBuilder:GET(oURI):Request.
oResponse = oClient:Execute(oRequest).
LOG-MANAGER:WRITE-MESSAGE(STRING(JsonString)).
LOG-MANAGER:WRITE-MESSAGE(oResponse:ContentType).
Examples of how to process different content types are provided in the following topics:
• String response on page 30
• JSON response on page 30
• XML response on page 31
• Binary response on page 32
• Multipart response on page 32
Note:
• Response messages with error codes such as 404 or 501 do not cause the ABL HTTP client to throw the
errors. They are processed just like any other response.
• If the HTTP client is unable to transform the response body to an object type that represents the Content-Type
header (as listed in the previous table), the data is returned as bytes of type OpenEdge.Core.Memptr.
The content type is changed to application/octet-stream. The original content type header returned
by the server is set to X-Orig-Content-Type. You should, therefore, check the response's ContentType
header as well as the ABL object type of the response's Entity property, when deciding how to handle
the response.
String response
To process a string in the response message, cast the Entity field in the response object to an
OpenEdge.Core.String object. For example:
USING OpenEdge.Net.HTTP.*.
USING OpenEdge.Net.URI.
USING Progress.Json.ObjectModel.*.
//Build a request
oURI = URI:Parse("http ://httpbin.org/robots.txt").
oRequest = RequestBuilder:GET(oURI):Request.
//Execute a request
oClient = ClientBuilder:Build():Client.
oResponse = oClient:Execute(oRequest).
JSON response
To process JSON content in the body of the response message, cast the Entity field of the response message
to a JsonObject, as shown in this example:
USING OpenEdge.Net.HTTP.*.
USING OpenEdge.Net.URI.
USING Progress.Json.ObjectModel.*.
//Build a request
oURI = URI:Parse("http://httpbin.org/json").
oRequest = RequestBuilder:GET(oURI):Request.
//Execute a request
oClient = ClientBuilder:Build():Client.
oResponse = oClient:Execute(oRequest).
oJsonObject:Write(JsonString, true).
MESSAGE string(JsonString).
XML response
If the content type in the response message is set to text/xml or application/xml, the XML content can
be accessed as an ABL X-DOCUMENT object. To process the XML content, cast the Entity field to an
OpenEdge.Core.WidgetHandle object and copy the resulting value to an X-DOCUMENT handle. For example:
USING OpenEdge.Net.HTTP.*.
USING OpenEdge.Net.URI.
USING Progress.Json.ObjectModel.*.
USING OpenEdge.Core.WidgetHandle FROM PROPATH.
//Build a request
oURI = URI:Parse("http://httpbin.org/xml").
oRequest = RequestBuilder:GET(oURI):Request.
//Execute a request
oClient = ClientBuilder:Build():Client.
oResponse = oClient:Execute(oRequest).
Binary response
To process images or files that are returned in an HTTP response message, cast the Entity field in the
response message to a ByteBucket as shown in this example:
USING OpenEdge.Net.HTTP.*.
USING OpenEdge.Net.URI.
USING Progress.Json.ObjectModel.*.
USING OpenEdge.Core.Memptr FROM PROPATH.
USING OpenEdge.Core.ByteBucket FROM PROPATH.
USING OpenEdge.Net.HTTP.Lib.ClientLibraryBuilder.
//Build a request
oURI =
URI:Parse("https://raw.githubusercontent.com/PeterJudge-PSC/http_samples/master/http_client/multipart_messages/smile.png").
oRequest = RequestBuilder:GET(oURI):Request.
//Execute a request
oLib = ClientLibraryBuilder:Build():sslVerifyHost(NO):Library.
oClient = ClientBuilder:Build():UsingLibrary(oLib):Client.
oResponse = oClient:Execute(oRequest).
Multipart response
To process a multipart response message, cast the Entity field of the response message to a
MultipartEntity object, as shown in this example:
USING OpenEdge.Net.HTTP.*.
USING OpenEdge.Net.URI.
USING OpenEdge.Net.MessagePart.
USING OpenEdge.Net.MultipartEntity.
//Build a request
oURI = URI:Parse("http://httpbin.org/get").
oRequest = RequestBuilder:POST(oURI):Request.
//Execute a request
oClient = ClientBuilder:Build():Client.
oResponse = oClient:Execute(oRequest).
Custom headers can be added to an HTTP request using the AddHeader() method of the RequestBuilder class. This method allows for multiple invocations to set various headers needed for the request. For example, you can use the following syntax to add headers: oRequest = RequestBuilder:Build('GET', oURI):AddHeader('MyCustomHeader','MyValue'):AddHeader('AnotherHeader','AnotherValue'):Request .
The IHttpClient interface plays a central role in executing HTTP requests in OpenEdge as it defines the Execute() method essential for sending requests to a server and receiving responses. The interface is implemented by building a client object through the ClientBuilder:Build():Client method. IHttpClient provides capabilities such as managing retries, setting timeouts, and supporting secure connections through TLS settings, making it critical for robust HTTP communication .
Path parameters can be included in a URI using the AddPathSegment() method of the OpenEdge.Net.URI object. This approach facilitates the dynamic construction of URIs by appending path segments to an existing URI structure. For example, an initial URI is built, and then method calls like oURI:AddPathSegment('1') are used to modify the path, enabling precise endpoint targeting within applications .
To execute an HTTP POST request with JSON data using OpenEdge.Net.HTTP, first construct a JsonObject representing the payload. Use this object as the request body by passing it to the RequestBuilder associated with the POST method. The process involves: (1) Creating a JsonObject and adding properties, (2) Building the request with RequestBuilder:POST(), supplying the JsonObject, (3) Executing the request using an IHttpClient instance, and (4) Handling the response, typically confirming success through status checks .
Multipart message handling in OpenEdge is implemented using the MultipartEntity and MessagePart classes. When processing a multipart response, the Entity field of the response is cast to a MultipartEntity object, which allows access to each part of the message. Each message part, represented as a MessagePart object, can be individually processed to retrieve its body content using the GetPart() method in a loop over the number of parts. This approach ensures comprehensive handling of complex payloads within a singular HTTP interaction .
Authentication in an HTTP request using the OpenEdge.Net.HTTP library can be implemented by using the UsingCredentials() method on the RequestBuilder. This method attaches a Credentials object containing the necessary authentication details such as username and password to the request. Alternatively, for OAuth or similar token-based authentication, the AddHeader() method can be used to include the Authorization header directly within the request, such as a bearer token .
To process a JSON response in ABL using OpenEdge.Net.HTTP, first, construct and execute the HTTP request. Upon receiving the response, check the status code to ensure it's 200. Then, cast the Entity field of the IHttpResponse object to a JsonObject, allowing you to manipulate and read the JSON data. For instance: IF oResponse:StatusCode <> 200 THEN RETURN ERROR "Request Error" ELSE oJsonObject = CAST(oResponse:Entity, JsonObject). Next, utilize methods on the JsonObject to extract required data .
Managing timeouts and retries in HTTP requests using OpenEdge.Net involves using the SetRequestTimeout() and SetNumRetries() methods on the client object built by ClientBuilder. SetRequestTimeout() sets a timeout for establishing HTTP connections, while SetNumRetries() specifies the number of retries for a failed request. By tuning these parameters, developers can ensure HTTP requests are robust and adaptable to network conditions, enhancing reliability and user experience .
Handling a binary response in OpenEdge involves casting the Entity field of the IHttpResponse to a ByteBucket, allowing operations on binary data received from the server. After the cast, the binary data can be extracted using methods like GetBytes(), which retrieve the response data from the ByteBucket. A common application includes saving image files locally using the COPY-LOB statement to write the binary data to a file after processing .
The RequestBuilder class in the OpenEdge.Net.HTTP framework is crucial for constructing HTTP request messages in ABL because it implements the fluent interface pattern, allowing developers to build requests flexibly and concisely by chaining method calls. This class supports various HTTP methods such as GET, POST, PUT, DELETE, and more. Developers can also add headers, specify content types, and manage authentication through the methods provided by the RequestBuilder. This design encapsulates the complexity of HTTP request creation while providing extensibility and ease of use .