MashZone NextGen 10.2 | Appendix | Legacy Presto components | Mashables and Mashups | Mashups in EMML | Writing Mashups in EMML | Invoking Component Mashups and Mashables | <directinvoke> | directinvoke Examples
 
directinvoke Examples
<directinvoke> Basics for GET Requests
Add a <directinvoke> element to the mashup script. Identify the endpoint (the URL) to the web service or web site, the HTTP method (GET or POST) to use to send the request and the outputvariable to receive the results from the web service or site.
Note: URLs sometimes include characters, such as & which must be escaped in XML. See XML Escaping in URLs and Expressions for more information.
You can also set bypassproxy to bypass the proxy server for this request.
If the endpoint is for a syndicated feed, you can also identify the format you want results normalized to in the feedtype attribute. Choose atom = ATOM 1.0, rss = RSS 2.0, or native = do not normalize the results.
Note: For Google News feeds, there is a known issue when feedtype ="atom". Simply remove the feedtype attribute to avoid this problem.
For example:
<directinvoke endpoint="http://www.myCompany.com/rest-services/getNames"
method="GET" outputvariable="$result"/>
<directinvoke endpoint="http://www.AnotherSite.com/getInfo"
method="GET" bypassproxy="true" outputvariable="$result"/>
<directinvoke endpoint="http://rss.news.yahoo.com/rss/topstories"
method="GET" feedtype="rss" outputvariable="$news"/>
Passing Parameters in <directinvoke>
You can pass parameters to the web service or web site using any attribute name that is not defined in EMML. These attributes can also have a namespace, if needed.
Note: In most cases, parameters are used with the GET method. Some web services, however, require the POST method with name/value pairs that are url-encoded and have only simple values. In this case, you add these as named parameters. For more information, see <directinvoke> Basics for POST Requests
In the following example, the attributes query and appID are not defined in EMML. These will be passed as parameters to the web site.
<directinvoke endpoint="http://www.myCompany.com/products/getItems"
method="GET" outputvariable="$result" query="items=all"
appID="67GYH30N25" />
<directinvoke endpoint="http://www.svcsltd.com/getReservation"
method="POST" outputvariable="$news" xmlns:sc="http://www.svcltd.com/"
sc:date="20070515" sc:nights="3"/>
The second example shows the use of parameters with the POST method and includes a a namespace with additional attributes for request parameters. This namespace must be defined on the <mashup> element or on <directinvoke> itself.
<directinvoke> Basics for POST Requests
Web services may require complex parameters or input in a specific format, such as Atom, JSON, SOAP or other, vendor-specific formats. In these cases, you use the POST method in <directinvoke>. Web services may also simply specify that requests must use the POST method.
With the POST method, the parameters or other information for the request is usually specified in the body of the request. Because the format may be different, the request must also set the HTTP Content-Type header (sometimes called the MIME-type).
There are two basic patterns to use <directinvoke> with the POST method, based on the format of the content:
*Name/Value Pairs: in this case, the web service expects named parameters with simple values. The HTTP content-type is application/x-www-form-urlencoded.
For this type of content, you simply set the method attribute to POST and add the parameters as attributes just as you do for GET requests. The MashZone NextGen Server automatically adds the HTTP Content-Type header with a value of application/x-www-form-urlencoded. See Passing Parameters in <directinvoke> for an example.
*Any Content That Is Not Name/Value Pairs: this includes any content-type other than application/x-www-form-urlencoded or content that has complex parameters. Common examples are SOAP content, any XML content such as Atom + XML, XHTML, HTML, JSON or vendor-specific content.
For this type of content, you:
*Define the information for the body of the request in a <constructor> or <variable> statement or any statement where you can build a variable with literal XML content. See Constructing the Mashup Result, Inputs or Intermediate Variables for more information and examples.
The mashup can also receive the body as an input parameter. For example, you can send the content for a JSON request body. See Handling JSON Responses or Inputs for more information and examples.
*Use the requestbody attribute to point to the variable with the request content.
*If the web service requires name/value pairs as well as a complex body in the request, you cannot use both the requestbody attribute and request-specific attributes for the named parameters as you would for GET requests. Instead, set named parameters in the endpoint attribute and set parameter values explicitly or with dynamic mashup expressions. For example:
<directinvoke outputvariable="$blogresult" method="post"
endpoint="http://postURI?namedParam={$value1}"
requestbody="$xmlPost" header="$header"/>
See Dynamic Mashup Expressions for more information.
*Explicitly set the appropriate value for the HTTP Content-Type header in a variable. See Adding HTTP Headers to <directinvoke> Requests for an example.
*Use the header attribute to point to the HTTP headers to send in the request. See Adding HTTP Headers to <directinvoke> Requests and Adding HTTP Basic Authentication to <directinvoke> Requests for more information and examples.
This example shows a request body in Atom format:
<constructor outputvariable="xmlPost">
<entry xmlns='http://www.w3.org/2005/Atom'>
<title type='text'>My First Blog</title>
<content type='xhtml'>
<div xmlns="http://www.w3.org/1999/xhtml">
<p>This is my first blog and I’m not sure what to say.</p>
<p>"Hello World!" just seems silly.</p>
</div>
</content>
<author>
<name>Mia</name>
<email>mia@xyz.com</email>
</author>
</entry>
</constructor>
<constructor outputvariable="header">
<header>
<Content-Type>application/atom+xml</Content-Type>
</header>
</constructor>

<directinvoke endpoint="$bloggerURL" outputvariable="$blogresult"
method="post" requestbody="$xmlPost" header="$header"/>
<directinvoke> Basics for PUT and DELETE Requests
The requirements for direct invocations with the PUT or DELETE methods are somewhat similar to those for POST:
*PUT invocations typically have a request body that provides the data for the endpoint to add or update. DELETE may also have a request body, although this is less common.
Use the requestbody attribute to point to the variable with the content for the request body.
If the web service requires name/value pairs as well as a complex body in the request, you cannot use both the requestbody attribute and request-specific attributes for the named parameters as you would for GET requests. Instead, set the named parameters and values in the endpoint attribute. See <directinvoke> Basics for POST Requests for an example.
*The format and content for the request body depends entirely on what the endpoint requires. It can be XML, JSON or any endpoint-specific string format.
*For XML content, define the information for the body of the request in a <constructor> or <variable> statement or any statement where you can build a variable with literal XML content. See Constructing the Mashup Result, Inputs or Intermediate Variables for more information and examples.
*For JSON or any vendor-specific text format, build the content using <assign> or <script>. You can also pass the JSON as an input parameter to the mashup.
See Handling JSON Responses or Inputs for information and examples.
*Depending on endpoint requirements, you may also need to add specific HTTP headers to clarify the purpose of the request or the data type of the request body.
Use the header attribute to point to the HTTP headers to send in the request. See Adding HTTP Headers to <directinvoke> Requests for more information and examples.
This example shows the EMML for a PUT request to an endpoint for a CouchDB database. This endpoint requires a JSON object that is either an insert or an update to an existing 'document' in the database, based on the mode input parameter:
..
<input name="docId" type="string"/>
<input name="mode" type="string"/>
<input name="member" type="string"/>
<variables>
<variable name="idProp" type="string"/>
<variable name="nameProp" type="string"/>
<variable name="statusProp" type="string"/>
<variable name="reqBody" type="string"/>
</variables>

<!-- build JSON object for request body -->
<assign fromexpr="concat('{"id":"',$docId,'",')" outputvariable="$idProp"/>
<assign fromexpr="concat('{"name":"',$member,'",')"
outputvariable="$nameProp"/>
<assign fromexpr="concat('{"status":"',$mode,'"}')"
outputvariable="$statusProp"/>
<assign fromexpr="concat($idProp,$nameProp,$statusProp)
outputvariable="$reqBody"/>
<if condition="$mode='new'">
<directinvoke endpoint="http://myorg.com/memberDB/updates"
method="put" outputvariable="$updateResult" requestbody="$reqBody"/>
<else>
<header>
<If-Match>{$docId}</If-Match>
</header>
<directinvoke endpoint="http://myorg.com/memberDB/updates"
method="put" outputvariable="$updateResult" requestbody="$reqBody"
header="$header" />
</else>
</if>
...
For inserts with this example, no HTTP header is required. For updates, however, the endpoint uses the HTTP If-Match header to identify which 'document' to update in the database.
Adding HTTP Headers to <directinvoke> Requests
You can define HTTP headers in variables and pass them in the request to the web service or web site using the header attribute. The variable for the header must be a document type with a <headers> root node. Each HTTP header is an XML element child and the value for that header is the content of the XML element.
Note: You can use this syntax to pass basic HTTP authentication headers to a web service or web site.
For example:
<operation name="directWithHeaders">
<variable name="httpHeader" type="document">
<headers>
<Content-type>application/x-www-form-urlencoded</Content-type>
</headers>
</variable>
...
<directinvoke endpoint="http://www.myCompany.com/rest-services/getItems"
method="GET" outputvariable="$result" header="$httpHeader" />
...
Adding HTTP Basic Authentication to <directinvoke> Requests
Another common requirement is to send basic authentication information to the web service using the HTTP Authorization header. This requires that the username and password assigned to this header be encoded using Base64 as a single string.
You can use the built-in macro, computeBasicAuth to perform the Base64 encoding. This macro has two input parameters, for the user name and password, and returns the encoded string. For example:
<input name="username" type="string" default="user"/>
<input name="password" type="string" default="pw"/>
<variable name="basicauth" type="string"/>

<macro:computeBasicAuth user="$username" password="$password"
outputvariable="$basicauth"/>

<variable name="httpHeader" type="document"/>
<constructor outputvariable="httpHeader">
<headers>
<Authorization>{$basicauth}</Authorization>
</headers>
</constructor>
...
<directinvoke endpoint="http://www.myCompany.com/rest-services/getItems"
method="GET" outputvariable="$result" header="$httpHeader" />
...
Getting Headers, Status Codes and Cookies from <directinvoke> Responses
The body of the response from the web service or web site is placed in the output variable you specify. You can use the following attributes in <directinvoke> to define variables to hold header and other information from the response:
*responseheader = a variable to hold the HTTP headers from the response.
*responsecode = a variable to hold the HTTP status code from the response.
*cookies = a variable to hold any cookies returned by the response.
This example checks for the HTTP redirect status and invokes the web service if it is detected:
<operation name="directWithCookiesEtc">
<variables>
<variable name="result" type="document" />
<variable name="redirecturl" type="string" />
<variable name="responseHeader" type="document" />
<variable name="responseCode" type="string" />
<variable name="cookies" type="document" />
</variables>
<directinvoke endpoint="http://myCompany.com/some-service/getDoc"
method="POST" outputvariable="$result"
responseheader="$responseHeader" responsecode="$responseCode"
cookies="$cookies" />
<display message="Headers are" variable="$responseHeader" />
<display message="Cookies are" variable="$cookies" />
<display message="ResponseCode is" variable="$responseCode" />
<if condition="number($responseCode)=302">
<assign fromexpr="$responseHeader//Location/string()"
outputvariable="$redirecturl" />
<display message="Redirect to" variable="$redirecturl" />
<directinvoke endpoint="$redirecturl" method="GET"
responseheader="$responseHeader" outputvariable="$result"
responsecode="$responseCode" cookies="$cookies" />
</if>
...
Handling Redirects from the Endpoint
By default, <directinvoke> will follow redirects specified by the endpoint when the method is GET, but ignores endpoint redirects for other HTTP methods. You can explicitly control how <directinvoke> handles endpoint redirects using the followredirects attribute.
The examples shown below override the default behavior to ignore redirects for a GET method and follow redirects for a POST method:
<directinvoke endpoint="http://www.myCompany.com/products/getItems"
method="GET" outputvariable="$result" followredirects="false"/>
<directinvoke endpoint="http://www.svcsltd.com/getReservation"
method="POST" outputvariable="$news" followredirects="true" />
Dynamic Endpoints or Parameters for <directinvoke>
You can use the <template> declaration to allow the endpoint or parameters for <directinvoke> to be set dynamically. This technique uses dynamic mashup expressions to resolve the URL. For example:
...
<!-- allow users to select a symbol -->
<input name="ticker" type="string" default="GOOG"/>
<!-- variable used to construct the dynamic endpoint -->
<variables>
<variable name="result" type="document" />
<variable name="wholeURL" type="string" />
</variables>
<!-- template to construct dynamic endpoint -->
<template expr="http://finance.yahoo.com/q/pr?s={$ticker}"
outputvariable="$wholeURL"/>
<directinvoke endpoint="$wholeURL" method="POST" outputvariable="$result" />
...
See Dynamic Mashup Syntax for more information and example on using <template>.
<directinvoke> with a Security Profile
For endpoints that require a security profile to pass authentication or other secured connection information, you use <securityprofile> as a child of <directinvoke> to supply this information and <param> children in <securityprofile>.
MashZone NextGen includes security profiles for some very common security requirements that you may use. See Mashable Authentication with Security Profiles for information on these bundled profiles.
MashZone NextGen administrators can also add custom security profiles to MashZone NextGen. Contact your MashZone NextGen administrator for information on custom security profiles, if any.
Important: Currently, <directinvoke> supports only the CAS2 security profile bundled with MashZone NextGen.
A security profile is not required for secure connections to web sites or web services using one-way SSL. <directinvoke> does not support mutual SSL.
This example shows a direct invocation using the MashZone NextGen built-in CAS2 security profile:
...
<directinvoke endpoint="http://myorg.com/securedservice"
method="POST" requestbody="$body" outputvariable="$result" >
<securityprofile id="CAS2"/>
</directinvoke>
...
The security profile, in this case, does not require any additional information. In rare cases, you may need to supply a verification URL for the secured endpoint where the CAS Server can verify security tokens, such as in this example:
...
<directinvoke endpoint="http://myorg.com/securedservice"
method="POST" requestbody="$body" outputvariable="$result" >
<securityprofile id="CAS2">
<param name="casServiceUrl"
value="http://myorg.com/securedservice/verifyTokens"/>
</securityprofile>
</directinvoke>
...
Working Samples
Many of the sample mashup scripts for MashZone NextGen use <directinvoke>. Some samples of particular interest include:
*YahooHotJobsFilter (rssfilter.emml) for the basics on using GET
See Mashup Samples for a list of MashZone NextGen mashup samples and where to find them.

Copyright © 2013-2018 | Software AG, Darmstadt, Germany and/or Software AG USA, Inc., Reston, VA, USA, and/or its subsidiaries and/or its affiliates and/or their licensors.
Innovation Release