The logic for handling HTTP requests.
To create your own HTTP request, create a new component extending HttpRequest component.
It's a Kopytko convention to use .request as a suffix e.g. Search.request.xml.
If you need to aggregate the common logic of some of your requests (e.g. setting headers), create a component with that logic and extend it (MyRequest extends MyBackendServiceRequest extends HttpRequest).
HttpRequest has the following interface that should be extended in your Request derived component:
getRequestOptions(data)- returns an object implementing theHttpRequest~OptionsparseResponse(response)- returns a data object (e.g. node) based onHttpResponseobject fulfilled with data; the promise returned fromcreateRequest()function will be resolved with this object. The method is executed on a task threadgenerateErrorData(response)- returns custom error data object thrown on request failure; the promise returned fromcreateRequest()function will be rejected with this object. The method is executed on a task threadgetHttpInterceptors()- returns the list of HTTP request and response interceptors implementing theHttpInterceptorinterface
A minimal working example:
<?xml version="1.0" encoding="utf-8" ?>
<component name="UpdateUserRequest" extends="HttpRequest">
<script type="text/brightscript" uri="GetUserRequest.brs" />
</component>' UpdateUser.request.brs
function getRequestOptions(options as Object) as Object
return {
url: "https://my-user.com/endpoint",
method: "POST",
headers: {
header1: "header-value",
},
body: {
userID: options.userID,
username: options.username,
},
}
end function
function parseResponse(response as Object) as Object
user = CreateObject("roSGNode", "User") ' example custom roSGNode extending Node
user.status = response.raw.data.status
return user
end function
function generateErrorData(response as Object) as Object
apiError = CreateObject("roSGNode", "ApiError") ' example custom roSGNode extending Node
apiError.reason = response.failureReason
return apiError
end functionRequest options structure allowed to be returned by getRequestOptions function:
url- string - request URLheaders- associative array - headers fieldsmethod- string - HTTP methodbody- associative array - request bodybodyString- string - request body string, alternative forbodyqueryParams- associative array - with query paramscompression- (defalt: true) boolean - indicating if the request should be compressedtimeout- integer - time after which request should be aborted
To send a request, use the createRequest function. It will create a task instance, run it and return a Promise that is fulfilled or rejected with the result of the parseResponse or generateErrorData function.
createRequest has 3 arguments:
task- the name of a component extending theHttpRequest componentto be created or an instance of such component to be reuseddata- data necessary to send a request, passed togetRequestOptionsfunctionoptions- an AA object with additional options; currently supportstaskOptionsfield to pass options to the task component andsignalfor aborting request
Let's use an example from previous section:
data = {
userID: "UserID123",
username: "Joe Doe",
}
promiseChain = createRequest("UpdateUserRequest", data)
promiseChain.then(sub (user as Object): end sub, sub (apiError as Object): end sub)If you know that request is not needed anymore you can easily abort it by adding the AbortController's signal to your request and by calling abort method on that instance of AbortController.
To do that you can pass your instance of abort controller in the options of createRequest.
myAbortController = AbortController()
createRequest("RequestName", {}, {
signal: myAbortController.signal,
})
myAbortController.abort()AbortController contains also isAborted method which will return a boolean indicating if abort was called on it.
The catch/rejected handler of the promise will be invoked when request is aborted.
Kopytko HTTP module allows intercepting requests made by HttpService (e.g. for reporting purposes) by creating interceptor objects implementing the HttpInterceptor interface.
Initialise them in the init() function and return in the overwritten getHttpInterceptors function declared in HttpRequest component
Request can be intercepted by adding custom interceptors to the HttpService. Each time the request is made, the interceptor will be invoked with arguments: requestOptions and urlTransfer.
interceptRequest takes two arguments:
requestOptions- these are options with which request was senturlTransfer- an instance ofroUrlTransferthat is handling this request
Response can be intercepted by adding custom interceptors to the HttpService. Each time the request is made, the interceptor will be invoked with arguments: requestOptions and urlTransfer.
interceptResponse takes two arguments:
requestOptions- these are options with which request was senturlEvent- an instance ofroUrlEventthat is returned on request fulfill