|
|
YOUR FEEDBACK
SOA World Conference
Virtualization Conference $200 Savings Expire May 16, 2008... – Register Today! |
TODAY'S TOP SOA & WEBSERVICES LINKS Feature
CFMX & Web Services
By: Ron West
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:
Fundamentals of a Web Service
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?
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):
The Tags
-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:
Additionally, the cfargument tag has some optional attributes that add to its functionality:
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
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:
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);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
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
SUBSCRIBE TO THE WORLD'S MOST POWERFUL NEWSLETTERS SUBSCRIBE TO OUR RSS FEEDS & GET YOUR SYS-CON NEWS LIVE!
|
SYS-CON FEATURED WHITEPAPERS MOST READ THIS WEEK |
||||||||||||||||||||||||||||||