YOUR FEEDBACK
JavaOne 2008: Chris Keene's Prescription for Curing the Java Flu
Rob wrote: I have to agree with Chris - I have been a developer and Java a...
SOA World Conference
Virtualization Conference
$200 Savings Expire May 16, 2008... – Register Today!

SYS-CON.TV
TODAY'S TOP SOA & WEBSERVICES LINKS


CFMX & Web Services

Digg This!

Over the next few months ColdFusion developers across the globe will be handed the keys to a next-generation Internet application development model. The culmination of over four years of work, which began even before the current release of ColdFusion went into development, it will generate a revolutionary way to develop and share application data and business logic over the Internet.

For many who have been involved with CF since the early years, this model will be welcomed, and those of you who are just about to embark on your CF tour of duty are in luck. The ColdFusion MX (CFMX) development architecture will make developing and maintaining CF applications a whole lot easier. In addition, Macromedia has enriched the CF toolset to include the easiest procedures to deploy and invoke Web services.

This article:

  • Discusses the importance of Web services and addresses the necessary steps to set up and use Web services within a CF application

  • Explains how to create a Web service and outlines the functionality of the cfcomponent, cffunction, cfargument, and cfreturn tags

  • Discusses the cfinvoke and cfinvokeargument tags and explains how to consume a Web service through the use of CFScript (a Web service can be invoked through an HTML form and a Flash client as well)

    Fundamentals of a Web Service
    In the past it may have been difficult for "pure" CF developers to stay on top of the hoopla that surrounds Web services, let alone participate in a deployment project. Although there's been some integration available with JRun, the tools for such a developer simply didn't exist. It's important to understand the fundamentals of a Web service, because they'll play a large role in our future application development environment. Since I'm sure most of you are familiar with Web services, I'll keep the description brief.

    A Web service is specific code that exists on a network that is made available for use by other connected systems. To invoke a Web service you essentially call a method written on the remote system from a client. The method is code written in a particular language exposed through the combination of a SOAP engine and a transport engine. The SOAP engine takes input/output parameters and serializes/deserializes them into a particular XML format, SOAP (Simple Object Access Protocol). The transport engine sends the data over the Internet from its place of origin (a client) to its destination (a server). The most basic and probably most popular transport engine will be HTTP. The transport type, however, doesn't limit a Web service.

    A Web service is registered with the SOAP engine through description files. The engine is tightly integrated with the application server. Once the request arrives at the SOAP engine via the transport engine, the request is parsed and the code is invoked. The return data is then encapsulated into a SOAP response by the SOAP engine and sent back to the transport engine where it is relayed to the client that made the original request (see Figure 1). All of the method's input and output parameters, as well as the Web service code, can be accessed through a Web browser in the WSDL (Web Services Description Language) file. WSDL files are also written in XML and can be easily read. The actual format of the WSDL file is outside the scope of this article, but it's important to understand the mechanism used to describe the Web service.

    SOAP engines currently exist for many different platforms written in several different languages. Since the CFMX runtime engine is now J2EE compliant, and Apache has produced a SOAP engine for Java called AXIS, the two applications together create the foundation for Web services support in ColdFusion. Simply put, CFMX will provide the fastest way to deploy and consume Web services. CFMX has taken out a lot of the configuration details required to expose code through a Web service. It takes care of the registration required between your code and the SOAP engine and offers multiple options for the consumption of Web services written in many different languages.

    Could It Be Any Simpler?
    Methods (or functions) weren't available to CF developers until CF5 with the introduction of user-defined functions. UDFs allow for concisely written reusable code to be made available throughout an application. Internally, this is a great way to write reusable code. Unfortunately, the code isn't accessible from any external location, and the only way it can be distributed is if the source code is revealed.

    CFMX introduces components. From a ColdFusion Component (CFC) a Web service can be built instantly. In fact, there's little difference between the architectures for a component and a Web service. (The difference is discussed later, but for now they can be considered one and the same.)

    The code example in Listing 1 is a UDF from the example apps in CF5. The UDF converts degrees Celsius to degrees Fahrenheit and vice versa. In CF5 the code was included as a common library and could be accessed with code like:

    #TempConvert(temp, scale)#

    The UDF had two input parameters: ATemp (the temperature to be converted) and ItsScale (the scale for the given temperature). The parameters are passed to the function in sequential order. The return data is a simple string, which represents the temperature converted into the new scale. Again, this is a fantastic way to write and access reusable code within an application; however, a UDF can't be distributed easily.

    A few changes are needed to convert this code to a Web service, allowing you to distribute the functionality of the code easily and not lose control over the source (see Listing 2):

    1. Add the cfcomponent tag around the entire document. The tag lets the CF application server know how to process the code.
    2. Next, replace the Function line (and end line) from inside the cfscript tag with a cffunction tag that surrounds the entire cfscript tag.
    3. Remove the return lines and replace them with cfreturn tags outside the cfscript tag.
    4. Once required arguments are defined with cfargument tags, change the file name from cfm to cfc and you're finished.
    Except for the movement of code and a file rename, not much has changed on the code side, but a lot has changed on the application side. You've just created your first Web service - it's that simple! No description files, no registration, no server reboot. Now CF can register a method automatically with the built-in SOAP engine. Just a few lines of code, a simple rename of the file, and voilĂ , an instant Web service. The CFMX server understands how to expose the method so other applications written in other languages can access your code securely.

    The Tags
    The cfcomponent tag has a few optional attributes that add to its extensibility:

    • hint: Use this to add metadata that de-scribes your Web service.
    • extends: Add this attribute and you essentially borrow code from another CFC as if you explicitly called the other component with a cfinclude.
    • output: Add this attribute to automatically handle the output of #expr# tokens within cffunction tags. The cffunction tag has one required attribute:
    • name: This attribute registers the method name. In our example the name of the function is tempconvert. This is the method that will be invoked remotely.
    In addition, cffunction has optional attributes, as described here:

  • returnType: Use this when you return data to the client. The type is either any, array, binary, boolean, date, guid, numeric, query, string, struct, uuid, variableName, void (this option doesn't return a value), return. In the tempconvert example the return type was a string.

  • roles: This adds a comma-separated list of CF security roles allowed to access this function.

  • access: The level of access defined for the function:
    -private: Makes the function available to the component that calls this method
    -package: Allows the function to be made available to other components in a package (a package can be created as a collection of components)
    -public: Makes the function available to local requests only (i.e., not to any locations other than the local site)
    -remote: Makes the function available as a Web service; allows the function to be called both locally and remotely

    The cfargument tag has only one required attribute:

  • name: Refers to the name of the input parameter sent by the caller page.

    Additionally, the cfargument tag has some optional attributes that add to its functionality:

  • type: This attribute represents the expected data type of the argument. Valid values are any, array, binary, boolean, date, guid, numeric, query, string, struct, uuid, variableName.

  • required: Either true or false - if false, an additional attribute can be specified to define a "default" value for the argument.

    The example had two arguments, "ATemp" and "ItsScale"; both were of the type string and both were required. So the example now has two cfargument tags, which define those two arguments (pa-rameters) as required. The cfargument tag also tells users that the data type for these tags is of datatype string.

    The cfreturn tag acts just like the return line of the cfscript tag in our original UDF. As only one cfreturn tag can be present in a cffunction tag, only one value can be returned to the client that calls the page. However, different data types can be returned, so to return a set of data, just create a structure with the data and use cfreturn to send it back to the client.

    (Security and access are two very important parts of a Web service. For many Web services you'll want to restrict access entirely or just to certain portions of your Web service. The security aspect of Web services is discussed briefly later on.)

    Using the New Web Service Internally
    Earlier I mentioned that in CFMX a Web service is merely a component...with a slight difference. The only real difference between a component (code available only to an internal CF application) and a Web service (CF code available on remote systems through a SOAP call) is the attribute ACCESS in the cffunction tag. Set the ACCESS attribute to REMOTE and you designate the code as a Web service. Set it to any other value and you designate the code as a CFC.

    To invoke a Web service we must introduce a new tag, cfinvoke. Don't despair, though. If you like to use CFScript there's also a set of tools to call the Web service from within a CFScript tag - I'll discuss that as well. In addition, we need to talk a little more about the WSDL file (remember, this is the file formatted in XML that describes our Web service).

    When Web services first began, the WSDL file had to be produced by hand. As Web services technology advanced, tools were written on certain platforms that could analyze a Web service and create a WSDL file for you. In CFMX neither of these processes is necessary; in fact, CFMX simply creates a WSDL file on the fly. To view the WSDL for a Web service created in CFMX, merely point an XML-compatible browser at the Web service page and add the WSDL query string to the end (i.e., http://localhost:8500/cfdj/com/temp convert.cfc?WSDL). The browser returns the WSDL file automatically.

    Another great feature of CF Web services is that CFMX supports introspection. The CFMX server will display all of the methods available for all Web services written in CF. In addition, the CFMX server will display all of the input/output parameters and their data types for each method offered in the Web service. Currently, access to this functionality is available only to users who know the RDS password for the CFMX server. Check the CFMX documentation for more on introspection.

    Although comparable, a little more code is involved when you use the cfinvoke tag in place of a simple function call such as you have with a UDF. This tag offers a common methodology for connectivity to Web services, both internally and externally. The code required to connect to the TempConvert Web service (see Listing 3) allows for an interface into the methods of a Web service. Because our Web service has required parameters (arguments), you can see that nested inside the cfinvoke tag are two cfinvokeargument tags, which take data from the caller page to be passed to the Web service.

    The cfinvoke tag has a ton of options and you'll use the tag in different ways. It all depends on what your code invokes. For Web services we use:

  • webservice: This attribute value is the URL location for the WSDL file (discussed earlier). In addition, you can define a map to your Web service in the CF Admin under "Web Services." All you do then is place the Web service name here.

  • method: The name of the method (code enclosed in cffunction tag) goes here.

  • returnVariable: With this attribute you can name the return variable (data returned in the cfreturn tag). If you place "myVar" in here, you can output #myVar# anywhere on the page after the cfinvoke tag.

    You can use multiple cfinvoke tags in the same document.

    The Web service can also be consumed in a CFScript tag (see Listing 4). Simply create a Web service object and give it a name (this process will look familiar to anyone who's written script code to access a Java file or COM object). As in the use of the cfinvoke tag, just point to the WSDL file for the Web service (i.e., ws = createObject("webservice", "http://localhost:8500/cfdj/com/tempconvert.cfc?wsdl").

    To invoke a method for the Web service, simply use the dot notation with the Web service object name followed by the method name. To pass in arguments to the Web service in a script tag, pass them sequentially, the way they're passed in a UDF, that is, ws.doTempConvert(temp, scale).

    If you name the method call, you essentially name the return variable. You can then work with the output. This works the same as the returnVariable attribute in the cfinvoke tag:

    degs = ws.doTempConvert(temp, scale);
    writeOutput("Original Temp:" & temp
    & " " & scale & "<br>");
    writeOutput("Converted to: " & degs
    & " F");
    Important information to keep in mind is that a Web service can consist of any CF code. You can even use cfinclude inside the cffunction tag if you want to keep your code cleaner. Moreover, a Web service has access to all scope variables, which includes Application, Server, Session, and Client.

    Beyond Simple Web Services
    Our Web service had only one method (cffunction tag) that returned a simple string; ordinarily there would be multiple methods. Each method in a Web service is in charge of a particular task. In a sense, you want to define methods that operate together to perform a set of procedures within a particular domain.

    For instance, we could have added another method to our TempConvert Web service, getScale, which would track the scale for the current temperature conversion. If the getScale function were passed "C", it would return "F", and vice versa. Not a crucial function, but it extends the functionality of the Web service a bit. So in our example the TempConvert function would call the getScale function, pass the scale argument, and receive the opposite scale. We could then have combined the data from the getScale function with the converted temperature and returned an array. The temperature data could be stored in the first index and the newly converted temperature in the second index.

    Remember, it's possible to return an assortment of data types. It's this basic power of data representation that makes Web services so powerful. Disparate systems now have the ability to share complex data even if the applications are written in different languages. It can be a little tricky to share structures and queries with all languages, but it's possible, and as Web services develop it will become a lot easier.

    The CFMX Web service has a unique architecture, which aids in code reuse (see Figure 2). The portion of code (if any) between the cfcomponent tag and the list of methods (cffunction tags) is run every time a method within its body is called. You can refer to the code as the constructor. For instance, if you created a Web service that queried a table in the database and you wanted to return three different sets of data to the client - the record count, the query data itself, and the query data - as a WDDX packet, you'd design three methods - getCount, getDataQuery, and getDataWDDX. You'd position the query at the top of the page (within the cfcomponent tag, but before the cffunction tags). All three methods could use the data from the query and return the necessary data to the client. If you use the constructor wisely, it can save a lot of code and be useful when you extend another component.

    Since a Web service is essentially CF code, we have all of the same security practices available. You can secure a Web service with Web server authentication, CF application security, role-based security, or programmatic security. While the details for each of these techniques is outside the scope of this article, it's important to understand that all of the current methods for authentication are available to Web services as well.

    Where to Go from Here
    ColdFusion has entered a new era, and the ability to produce and consume Web services is only the start. What has been introduced in CFMX is a whole new way to communicate over the Web. All of the tools are available to CF developers to show the world what CF can do. Take some time and go through the documentation for CFCs and Web services. Once fully understood, the ideology behind CFCs and Web services should change the way you think about Web application development.

    About Ron West
    Ron West is a Senior Applications Developer with PaperThin, Inc., a privately held Web content management vendor headquartered in Quincy, Massachusetts. Ron has been working with Web applications for seven years. He is one of the directors of the Rhode Island ColdFusion User Group, and is an established writer for several industry publications.

  • Amjad Pendhari wrote: This is glad to read that the cold fusion community will be improved technically with the upcoming development of CFMX
    read & respond »
    SUBSCRIBE TO THE WORLD'S MOST POWERFUL NEWSLETTERS
    SUBSCRIBE TO OUR RSS FEEDS & GET YOUR SYS-CON NEWS LIVE!
    Click to Add our RSS Feeds to the Service of Your Choice:
    Google Reader or Homepage Add to My Yahoo! Subscribe with Bloglines Subscribe in NewsGator Online
    myFeedster Add to My AOL Subscribe in Rojo Add 'Hugg' to Newsburst from CNET News.com Kinja Digest View Additional SYS-CON Feeds
    Publish Your Article! Please send it to editorial(at)sys-con.com!

    Advertise on this site! Contact advertising(at)sys-con.com! 201 802-3021

    SYS-CON FEATURED WHITEPAPERS


    ADS BY GOOGLE