In this tutorial shows you how to send a request to an external API, get it served synchrionously, and get the response back to the original pipeline.
How to send a request to an external API via a sink of the
http-request
type.How to receive the response of an HTTP call via a source of the
http-response
type.How to co-relate the HTTP request and its response.
Before you begin:
In the previous tutorials you learnt how to create simple Siddhi applications and simulate virtual events to it. You also learnt how to capture events with WSO2 Stream Processor and publish the output as logs in the console.
In this tutorial we assume that you have gone through the previous tutorials and have an understanding of the above.
Resources
In this tutorial, you need to use an externally hosted service that can be accessed from here. This service returns the credit card type when a credit card number is submitted.
As shown in the above diagram, you can call an external service to obtain the credit card type by submitting the credit card number. Each API request is correlated with the corresponding API response (this is indicated in the diagram by the color iof each request and response).
Tutorial steps
- Start the WSO2 SP in the editor mode and login to the Stream Processor Studio. Then open a new Siddhi file.
Let's name the Siddhi application
Http_Request_Response_Tutorial
, and provide a description as shown below.@App:name("Http_Request_Response_Tutorial")
@App:description("This app demonstrate the usage of http request sink and http response source")
First, let’s specify the stream from which the input data for the request must be taken. In this scenario, the input data is the credit card number from which the credit card type needs to be derived. Therefore, let's define a stream named
CreditCardStream
with an attriburte namedcreditCardNo
.@App:name("Http_Request_Response_Tutorial")
@App:description("This app demonstrate the usage of http request sink and http response source")
define stream CreditCardStream (creditCardNo string);
Now you need to submit an HTTP request to an external API using the data extracted from the
CreditCardStream
stream. To do so, you need to configure an http-request sink. Let's add it to the Siddhi application as follows.@App:name("Http_Request_Response_Tutorial")
@App:description("This app demonstrate the usage of http request sink and http response source")
@sink(type='http-request',publisher.url='https://secure.ftipgw.com/ArgoFire/validate.asmx/GetCardType',method='POST', headers="'Content-Type:application/x-www-form-urlencoded'",
sink.id="cardTypeSink",
@map(type='keyvalue', @payload(CardNumber='{{creditCardNo}}')))
define stream CreditCardStream (creditCardNo string);
Note the following details relating to the above sink definition.
The
publisher.url
parameter specifies the URL to which the outgoing events need to be published via HTTP.The
method
parameter specifies the HTTP verb.- You need to set the required headers via the header parameter. In this scenario, the
Request details
of theResources
content type header required for the above post request is mentioned. You are also setting the request content type via theheader
parameter. - Define a value for the sink.id parameter. More details about these parameter are provided later in this tutorial.
- The sink configuration is added above the
CreditCardStream
definition to indicate that the events sent via this sink are taken from theCreditCardStream
stream. @map()
sub-annotation indicates the output mapping. The value for thecreditCardNo
attribute extracted from theCreditCardStream
stream is set to theCardNumber
attribute that needs to be sent in the payload of the POST request.
Now you need to configure a source to receive the response of the above http request. For that you can use a
http-response
type source.@App:name("Http_Request_Response_Tutorial")
@App:description("This app demonstrate the usage of http request sink and http response source")
@source(type='http-response' ,sink.id='cardTypeSink',
@map(type='xml', namespaces = "xmlns=http://localhost/SmartPayments/",
@attributes(creditCardNo = 'trp:creditCardNo',creditCardType = ".")))
define stream EnrichedCreditCardStream (creditCardNo string,creditCardType string);
@sink(type='http-request',publisher.url='https://secure.ftipgw.com/ArgoFire/validate.asmx/GetCardType',method='POST', headers="'Content-Type:application/x-www-form-urlencoded'",
sink.id="cardTypeSink",
@map(type='keyvalue', @payload(CardNumber='{{creditCardNo}}')))
define stream CreditCardStream (creditCardNo string);
Note the following details relating to the source configuration.
- Here, you are including the
sink.id
parameter with the same value (i.e.,cardTypeSink
) that was assigned to it in the sink configuration of thehttp-request
type. This is because the http-request sink is corelated with the http-response through this sink ID. Here, you are ensuring that the response for the HTTP request sent via your sink is received via the source with the same sink ID. @attributes
annotation indicates the attributes that need to be extracted from the response received via the http-response source.The response from the API call is as follows.
<?xml version="1.0" encoding="utf-8"?>
<string xmlns="http://localhost/SmartPayments/">VISA>
Therefore the map type needs to be
xml
. You also need to add a namespace within the mapping annotation to extract the value for thecreditCardType
attribute from the response using xpath as“ . ”
(because its the root element).- If you need to access the attributes of the HTTP request in the http response source, you can use
trp:<attribute_name>
. In this scenario, you are extracting the value for the credit card number astrp:creditCardNo
. - The source is connected to a stream named
EnrichedCreditCardStream
that lists the attributes inserted ascreditCardNo
andcreditCardType
.
- Here, you are including the