HTTP Access
Elements RTL provides the static Http
class and a suite of helper types around it, in order to facilitate making network requests using the HTTP (and HTTPS) protocols in a cross-=platform fashion.
Under the hood, Http
uses then networking infrastructure provided by each platform, meaning its a reliable and well-tested system fior making HTTP requests that is used by many developers and users every day, and subject to the continued improvements and security maintenance doe by the platform vendors. It wraps this infrastructure in a common API that can be use din the same way, on all platforms.
Http
does not (currently) provide all the bells for controlling every detail of the HTTP stack – you can fall back to the platform-specific APIs for that, if necessary – but it provides access to the most commonly needed functionality, incuding the ability to make GET
and POST
requests, access headers, and controll redirect handling.
By default, Http
is designed to be used asynchronously, meaning requests run in the background and will trigger callbacks as necessary. That is recommended practise on all platforms, and even mandatory on some (such as Windows Phone). Synchronous APIs are provided for use in server or command-line applications, but should be used sparingly.
ExecuteRequest()
The core API method on the Http
class is ExecuteRequest()
, which takes either an URL or a more well-configured HttpRequest
class instance, and initiates a request to that address. A callback block is provided thaty will be executed, once the request has been completed and a response (but not necessarily all the response data) has been received from the server.
Http.ExecuteRequest(new Url('http://www.elementscompiler.com'), response -> begin
// handle the response
end);
Http.ExecuteRequest(new Url("http://www.elementscompiler.com"), (response) => {
// handle the response
});
Http.ExecuteRequest(Url("http://www.elementscompiler.com") { response in
// handle the response
});
Http.ExecuteRequest(new Url("http://www.elementscompiler.com"), (response) => {
// handle the response
});
By default when just passing a Url
, ExecuteRequest
will perform a GET
request without content. You can also manually consttruct a HttpRequest
object and configure it in more detail, for example to make a POST
request, or send custom headers or a body with your request. We'll look at that in more detail later.
Once a response comes from the server, the provided callback block will be called, passing in a HttpResponse
object.
HttpResponse
HttpResponse
has a few properties and methods worth noting. First, the Success
property allows you to check whether the request succeeded or failed. If it failed (which could be due to network errors, a bad URL, or an error response from the server, you can check the Exception
property for details on the failure.
You can also manually check the HTTP response code via the Code
property, and inspect any Headers
the server returned.
Of course, the most interesting part of an HTTP request will be the returned data, the body of the response. Because the data returned by request can be large and/or slow to come in, that data is not immediately available as part of the response. In fact, data might still be coming in slowly but steadily over the network, as your response callback is already executing.
HttpResponse
has a few helper methods that let you get access to the response content, asynchronously. Just as with the initial request, you will call (one of) these methods, and pass a block that will be called back once the data bas been received. Currently, four methods are provided that will return the data in different formats, depending on our needs. Over time, additionaklm formats may be added. These methods are:
method GetContentAsString(aEncoding: Encoding := nil; contentCallback: HttpContentResponseBlock<String>);
method GetContentAsBinary(contentCallback: HttpContentResponseBlock<Binary>);
method GetContentAsXml(contentCallback: HttpContentResponseBlock<XmlDocument>);
method GetContentAsJson(contentCallback: HttpContentResponseBlock<JsonDocument>);
void GetContentAsString(Encoding aEncoding = null, HttpContentResponseBlock<String> contentCallback);
void GetContentAsBinary(HttpContentResponseBlock<Binary> contentCallback);
void GetContentAsXml(HttpContentResponseBlock<XmlDocument> contentCallback);
void GetContentAsJson(HttpContentResponseBlock<JsonDocument> contentCallback);
func GetContentAsString(_ wncoding: Encoding? = nil; _ contentCallback: HttpContentResponseBlock<String>)
func GetContentAsBinary(_ contentCallback: HttpContentResponseBlock<Binary>)
func GetContentAsXml(_ contentCallback: HttpContentResponseBlock<XmlDocument>)
func GetContentAsJson(_ contentCallback: HttpContentResponseBlock<JsonDocument>)
void GetContentAsString(Encoding aEncoding = null, HttpContentResponseBlock<String> contentCallback);
void GetContentAsBinary(HttpContentResponseBlock<Binary> contentCallback);
void GetContentAsXml(HttpContentResponseBlock<XmlDocument> contentCallback);
void GetContentAsJson(HttpContentResponseBlock<JsonDocument> contentCallback);
You will note that, aside from the optional Encoding
parameter for GetContentAsString
, all four versions look identical, expept for the generic parameter to the callback block.
Calling any of these methods, the Http
class will go out in the background, retrieve the full data for the request and – here necessary decode it to a String, Json or Xml object. Once done, the provided callback block will be called.
HttpResponseContent<T>
Just like the response, the passed HttpResponseContent
object will have a Success
property that indicates if everything went well (for example, the data might not be valid XML, or the data might not be convertable as a string with the given encoding). If everything worked, the Content
property – generically typed to be the right kind of data you would expect – gives you access to the received content.
Http.ExecuteRequest(new Url('http://www.elementscompiler.com'), response -> begin
if response.Success then begin
response.GetContentAsString(nil, content -> begin
if content.Success then
writeLn('Response was: '+content.Content);
end);
end;
end);
Http.ExecuteRequest(new Url("http://www.elementscompiler.com"), (response) => {
if (response.Success)
{
response.GetContentAsString(null, (content) => {
if (content.Success)
writeLn("Response was: "+content.Content);
});
end;
});
Http.ExecuteRequest(Url("http://www.elementscompiler.com") { response in
if response.Success {
response.GetContentAsString(nil) { content in
if content.Success {
writeLn("Response was: "+content.Content);
}
});
};
});
Http.ExecuteRequest(new Url("http://www.elementscompiler.com"), (response) => {
if (response.Success)
{
response.GetContentAsString(null, (content) => {
if (content.Success)
writeLn("Response was: "+content.Content);
});
end;
});
To do: to be concluded