The URL returns an XML document, which you can manipulate
in any way that you wish. To learn more about how to use
the XML feed, read Nate Weiss’ tutorial, Utilizing
XML and XSLT in ColdFusion MX.
Building a custom function to retrieve the Amazon.com
feed
This section explains how to write a user-defined function
to retrieve the Amazon.com XML feed. You can use the new
ColdFusion MX cffunction tag with cfhttp to retrieve and
return the XML feed. The following custom function will
return a static URL:
<cffunction name="AmazonKeywordSearch">
<cfhttp url="http://rcm.Amazon.com/e/cm?t=instantcoldfu-20&mode=books&search=ColdFusion& l=st1&p=102&o=1&f=xml"
method="get" timeout="60">
<cfreturn #cfhttp.fileContent#>
</cffunction>
<cfset macromedia = AmazonKeywordSearch()>
<cfoutput>#htmlCodeFormat(macromedia)#</cfoutput>
This function is named AmazonKeywordSearch. It is set up
with the cffunction tag. Inside the tag, the cfhttp tag
is used to retrieve the static URL. The cfreturn tag is
used to return the value returned by the URL. This is functional,
but it is not flexible. Every time that the function is
called the same results are returned. This occurs because
the user cannot specify arguments for the URL parameters
in the specified URL.
There are four elements that a user for this web service
could specify to retrieve a customized resource feed from
Amazon.com: the associate ID, the mode value, the browse
ID, and the search string. Since the mode and browse arguments
cannot be used together, the updated function will only
have the one of those attributes specified: mode attribute.
When the Associate ID is turned into a web service, it leaves
two arguments that are passed into the function: the mode
attribute and the search string. You’ll use the cfargument
tag to define arguments in the function. The updated function
is as follows:
<cffunction name="AmazonKeywordSearch">
<cfargument name="Mode" type="String"
required="yes">
<cfargument name="Search" type="String"
required="yes">
<cfset var AmazonURL = "http://rcm.Amazon.com/e/cm?t=instantcoldfu-20&l=st1&search="
& #arguments.search# & "&mode=" &
#arguments.mode# & "&p=102&o=1&f=xml">
<cfhttp url = "#AmazonURL#" method = "get"
timeout="60">
<cfreturn #cfhttp.fileContent#>
</cffunction>
This function now accepts two arguments, a mode argument
and a search argument. A local variable, named AmazonURL,
is created in the function using cfset with the var keyword.
This variable creates the URL by piecing together the dynamic
and static portions of the URL. Finally, the cfhttp tag
is used to retrieve the URL and the cfreturn tag is used
to return the results. The XML feed can be retrieved using
this code. The cfdump tag displays the output for the function:
<cfoutput>
<cfdump var="#AmazonKeywordSearch('books','ColdFusion')#">
</cfoutput>
You can add the cfdump code below the function to see the
output results.
Creating the ColdFusion Component
You can easily convert the custom function in the
previous step into a ColdFusion Component (CFC). Take the
custom function code and place it in a file named: AmazonXMLFeed.cfc.
Note that the file has the CFC extension. In the process
of creating the component, you’ll add functionality
that allows the ColdFusion component to handle the Amazon.com
Associate ID.
Important note: If you save your CFC file
in a virtual directory, ColdFusion cannot inherently access
it to display the CFC metadata code. If you try to access
it, you will receive an error. The workaround for this is
to create a ColdFusion mapping that is identical to your
virtual directory mapping. Once that is done, ColdFusion
will have no problems displaying the CFC metadata. Or, if
you do not wish to create a ColdFusion mapping, you can
place the code in a directory within your webroot.
First, add the initialization code to the component. Initialization
code is code that executes when the component is instantiated;
it is inside a component, but not inside a method. The initialization
code is as follows:
<cfset this.AssociatesID = "instantcoldfu-20">
This initialization code creates a variable in the this
scope. The this scope is a scope available only to code
inside the component. The variable is named AssociatesID
and contains a default value for the AssociatesID.
The second element that must be added to component is a
way to change the AssociatesID. Adding the following function
accomplishes this requirement:
<cffunction name="AmazonSearchInitialize"
returntype="string" output="false">
<cfargument name="AssociatesID" type="string"
required="yes">
<cfset this.AssociatesID = #arguments.AssociatesID#>
<cfreturn this.AssociatesID>
</cffunction>
The function is named AmazonSearchInitialize. It accepts
one argument, AssociatesID. The argument is specified with
the cfargument tag, which is required and must be a string.
The next line sets the AssociatesID variable to the value
of the argument that was passed into the function. The function
does not explicitly return a value.
Next, you’ll need to modify the AmazonKeywordSearch
function to take advantage of this new AssociatesID variable:
<cffunction name="AmazonKeywordSearch"
returntype="string" output="false">
<cfargument name="Mode" type="String"
required="yes">
<cfargument name="Search" type="String"
required="yes">
<cfset var AmazonURL = "http://rcm.Amazon.com/e/cm?t="
& #this.AssociatesID# & "&l=st1&search="
& #arguments.search# & "&mode=" &
#arguments.mode# & "&p=102&o=1&f=xml">
<cfhttp url = "#AmazonURL#" method = "get"
timeout="60">
<cfreturn #cfhttp.fileContent#>
</cffunction>
The line that creates the variable named AmazonURL changes.
Instead of using a static Associate ID value, it is replaced
with the dynamic variable AssociatesID. This component is
more flexible than the original user-defined function.
To invoke the ColdFusion component functions, create a
new ColdFusion page, named test.cfm. Place the following
code in test.cfm to invoke the ColdFusion component. First,
to create an instance of the component, use the cfobject
tag with the component and name attributes:
<cfobject component = "AmazonXMLFeed"
name = "AmazonResourceFeed">
Next, add the cfobject tag, which specifies the name of
the component without the ColdFusion Component (CFC) extension
(AmazonXMLFeed) and the name of the variable that specifies
the component instance, AmazonResourceFeed. To invoke individual
methods, use the cfinvoke tag:
<cfinvoke component="#AmazonResourceFeed#"
method="AmazonSearchInitialize" AssociatesID =
"instantcoldfu-20" returnvariable="Test">
The cfinvoke tag uses the component attribute to specify
the component object. Pound signs surround the object name.
The method attribute specifies the function to invoke. The
AssociatesID attribute specifies the parameter to send to
the method. The returnvariable specifies the variable that
will contain the result.
Browse test.cfm. This will return the AssociatesID value
that you entered. If you wish to invoke the second function,
change the cfinvoke tag to:
<cfinvoke component="#AmazonResourceFeed#"
method="AmazonKeywordSearch" mode="books"
search="ColdFusion" returnvariable="Test">
Note that the method value has changed to the second function
name, and that the attributes match the arguments defined
in the AmazonKeywordSearch function.
Turning the Component into a web service
Finally, you’ll learn how to turn the ColdFusion component
into a web service. If you haven’t read the ColdFusion
MX’s web services documentation, you should read it
before proceeding. See Developing
ColdFusion MX Applications with CFML for more information.
You can turn a CFC into a web service by changing its access
attribute value to “remote” within the cffunction
tag (access=”remote”). The default access attribute
value is “public,” which means that the function
is available to all local pages. If you specify access=”remote”
in the cffunction tag, it makes the CFC available to remote
clients who can call its methods through URL, a Macromedia
Flash movie (through Macromedia Flash Remoting), or using
SOAP—these remote clients are accessing the component
as a web service. The complete CFC code is shown below:
AmazonXMLFeed.cfc
<cfcomponent output = "false">
<!--- Code to inititalize AssociatesID –-->
<cfset this.AssociatesID = "instantcoldfu-20">
<!--- function to initialize the AssociateID of the component
--->
<cffunction name="AmazonSearchInitialize" access="remote"
returntype="string" output="no">
<!--- Define the AssociatesID argument --->
<cfargument name="AssociatesID" type="string"
required="yes">
<!--- set the AssociatesID argument --->
<cfset this.AssociatesID = #arguments.AssociatesID#>
<cfreturn this.AssociatesID>
</cffunction>
<!--- function to perform an Amazon.com keyword search
--->
<cffunction name="AmazonKeywordSearch" access="remote"
returntype="string" output="no">
<cfargument name="Mode" type="String"
required="yes">
<cfargument name="Search" type="String"
required="yes">
<cfset var AmazonURL = "http://rcm.Amazon.com/e/cm?t="
& #this.AssociatesID# & "&l=st1&search="
& #arguments.search# & "&mode=" &
#arguments.mode# & "&p=102&o=1&f=xml">
<cfhttp url = "#AmazonURL#" method = "get"
timeout="60">
<cfreturn #cfhttp.fileContent#>
</cffunction>
</cfcomponent>
The CFC contains the two functions, AmazonSearchInitialize
and AmazonKeywordSearch. These functions were created in
the previous CFC. Both functions added a returntype and
specified the output attribute with the value no. It also
contains the code that was examined to initialize the AssociatesID.
Since the access attribute for each of the functions is
“remote,” they can be accessed as web services.
To access them as web services, generate the Web Service
Definition Language (WSDL) file. ColdFusion will create
the WSDL file automatically if you load the CFC file in
the browser and add ?wsdl to the query string, such as http://localhost/AmazonXMLFeed.cfc?wsdl
(Note: replace “localhost” in the URL and port
as appropriate to your setup).
Next, create a file called test2.cfm that will invoke the
new CFC. It will contain the following code:
<cfobject webservice="http://localhost/AmazonXMLFeed.cfc?wsdl"
name="AmazonResourceFeed">
Important note: Change the URL for the
webservice attribute based on the location of your CFC.
Once the web service is created as an object, you can execute
individual methods using the cfinvoke tag. There is little
difference between calling the web service through the cfinvoke
tag and the way that you called methods from the component:
<cfinvoke webservice="#AmazonResourceFeed#"
method="AmazonKeywordSearch" mode = "books"
search = "ColdFusion" returnVariable="AmazonKeywordSearchResults">
The cfinvoke method uses the webservice attribute instead
of the component attribute. The other attributes and parameters
to the method remain unchanged. The results will be the
same block of XML. Lastly, add the cfdump tag, which will
output the results:
<cfdump var="#XMLParse(AmazonKeywordSearchResults)#">
Browsing test2.cfm will display the following in your browser: |