Writing CFC's and Web Services

CFC?s and web services. What can you do with them and how can you implement them? This is what we are going to address in this tutorial. First, we will give you a definition of what they do and their differences, then we will show you how to write your own. First, I would suggest downloading the support files, which can be downloaded by clicking here. They include an Access database that we will be working with. We will make a data source that points to the database, which we will name ?cfc_tutor?. You can name it anything you want, but it will be referred in this tutorial as ?cfc_tutor?.

First, we would like to stress that this is not a tutorial for the beginner. You do not have to be a guru either, but it does help if you have experience writing ColdFusion custom tags. Second, CFC?s require ColdFusion MX server. If you do not have it, I would suggest installing it. They offer a free developer?s edition that you can download from Macromedia.com. 

So what is a CFC? CFC stands for ?ColdFusion Component?. They are like objects, well, they are kind of like objects. We know that ColdFusion is a tag based programming language, but those familiar with other programming languages will understand the difference between ColdFusion and an object oriented language. Objects are reusable application bits, much like a custom tag. 

So you have some understanding what a CFC is, so what is the difference between a CFC and a web service? Well, there is not much difference in the writing of one, but a web service will allow you to connect to this ?object? which can reside on another web server and return the data to the application requesting it. Let?s write a CFC to help you better understand the functionality. After we write the CFC, we will then make it an available web service and you will see the difference. These will be simple CFC?s, but will get you started on the functionality of CFC?s.

First we will create a new file in Studio (or whatever might be your preferred editor). Let?s save this file as ?CFCTUTOR.CFC?. It is very important that you start with a completely blank document, so if you are using Studio, get rid of those default HTML tags. Let?s now define this as a Component. Simply write the CFCOMPONENT tags:

<CFCOMPONENT>

</CFCOMPONENT>


So now we got a component! That was a lot of work, but we are not finished yet. What this component needs is a function. A function is what you call within the component. If you know JavaScript, you know of defined functions, this is not much different if you take a close look, but it is tag based as ColdFusion is legendary for.

So let?s make a function that returns the first name of the employee that matches a certain last name that resides in our database. We will pass it a last name, look for the first name, and return it as a string. Lets start by creating the function:

<cffunction name="ReturnFirstName" access="public" returntype="string" hint="This will return the first name when passed a last name">

</cffunction>

We have called this function ?ReturnFirstName?. Remember, you can not use underscores in the names of the functions, so if that was your original naming convention, you need to move away from that when writing functions. We gave it public access; this means that we are making the component available locally to an executing page or another component method. This can not be connected to and used via a URL, we will do that later. We set the return type as a string, since that is what we will be returning. There are many other options to return, they are worth taking a look at so you will know your options later and any limitations. The hint attribute is just that, a hint. Think of it as self commenting your code, this can be seen when you are analyzing your component or web service.

Now we will define the arguments we will be using in this tag. I think the simplest argument name we can use is ?LastName?, since that is pretty descriptive to what we will be asking for. It is always a good idea to be as descriptive as possible, but try not to make the arguments or functions so long it is impossible to read quickly, for they may be misspelled or misread. So lets define the argument we will need for this function:

<cfargument name="LastName" type="string" required="yes">

As you look at this, you will see that the argument name is ?LastName?, as we decided on earlier. The type defines the type of input we are to be expecting; in this case we are accepting a string for the last name. The types are the same as the returntype argument in CFFUNCTION, so they are worth taking a look at again to see where your limitations are. We also have the option of setting if the argument is required or not. We set this to ?yes?, as this function will not work without this argument. If it is not required, you can always set this to ?no?.

Now let?s go ahead and write the query to get the first name of the employee:

<CFQUERY name="get_employees_first_name" datasource="cfc_tutor">
    select first_name
    from employees
    where last_name = '#arguments.LastName#'

</CFQUERY>


This is a simply query that I am sure you have written hundreds of these. A good rule is to try to be as descriptive about the query name as you can be. Notice that the argument we will be passing was called ?LastName?, I am calling this in the CFC not by simply ?LastName?, but I am appending ?Arguments.?. This is very important.

Now that we have the query written and this is finally coming together, lets return the first name:

<CFRETURN get_employees_first_name.first_name>

That is all we have to do to return the first name. You do not need quotes around the return, unless you are returning a string that is not a defined variable, such as ?Hello World? would need quotes, but if hello_world was a variable and you wanted to return the value, you would not use quotes. 

Save this file and lets create a page to call this function. It is very important that you save this new page in the same directory as the CFC. Now lets invoke the object and send it the argument that is needed to complete the process:

<CFINVOKE component="cfctutor" method="ReturnFirstName" returnvariable="foo">
    <CFINVOKEARGUMENT name=
"LastName" value="Duck">
</CFINVOKE>


That is how we will invoke the object in a ColdFusion document. Let?s go over the arguments we passed to the CFINVOKE tag. The component is the name of the CFC, just take away the .cfc and that would be your component name. The method is the function we are calling, and as you recall, we only have 1 function available at this time, and the return variable is the name we are giving the data that is returning to us. 

Between the CFINVOKE tags we are passing the argument, which is ?LastName?, and giving it a value of ?Duck?. This should return Mr. Ducks first name for us, but we need to display the data we will be getting back. This is simple; we already told the component that we want the return variable to be ?foo?, so we just add this below the CFINVOKE tag:

<CFOUTPUT>
    #foo#
</CFOUTPUT>


Go ahead and save the CFM file and run it, you should simply get the name ?Daffy? returned as Mr. Ducks first name. Now I am aware that this component really has limited functionality, but the purpose of this tutorial is to give you a basis of what can be done. Let?s write one more component, and then we will move to web services.

Now let?s say we want to return all the employees and all the data in the database. We could not simply return this as a string, so ColdFusion gives us the option to return queries, which can be very helpful in developing components. Let?s start a new function and call it ?GetAllEmployeeData?.

First we will define the function, still in between the CFCOMPONENT tags:
<cffunction name="GetAllEmployeeData" access="public" returntype="Query" hint="This will return all the employee data as a query">

</cffunction>

Take a look at how this differs from our first function. We have given it a different name obviously as well as a different return type and a hint that describes what this function will do. 

Now for the simple query to get the data that is needed. Since we are not going to need any arguments, we will be skipping that tag. Here is the query:

<CFQUERY name="get_all_employee_data" datasource="cfc_tutor">
    select first_name, last_name, salary
    from employees

</CFQUERY>


There is the query, now all we have to do is return the information. This is done the same way we returned the other data, except we only give it the name of the query, no other information is needed. 

<CFRETURN get_all_employee_data>

Now we are returning the data, yippee! Now let?s go back to the page we wrote to use our last function, and we will append to the document. 

First we start off by invoking the function:

<CFINVOKE component="cfctutor" method="GetAllEmployeeData" returnvariable="foo2">

</CFINVOKE>

All we changed was the method we are going to be calling, and the variable name, since we are already using the variable ?foo?, I named it ?foo2?. There are no arguments, so we do not need to pass any with the CFARGUMENT tag. 

Now we can display the data as we would with any query:

<CFOUTPUT query="foo2">
   
#first_name# #last_name# #salary#<BR>
</CFOUTPUT>


That?s it! How easy is that? Now say we want to have access to this as a web service, for other servers or for others to use? The first thing we need to do is go back to ?cfctutor.cfc? and change the access for the functions to ?remote?. If we do not want access to all our components, we can make some public and some remote, remote allows for a remote system to call them and use them. For this exercise, let?s make them all remote. With this as the access type, we can use them locally and allow others to connect to them. One important note, the return type ?query? does not seem to work in ASP or PHP, I have only gotten it to work in JSP and CF, so you may want to make your query an XML object if you want this data available to others not on the JSP or CF platform. 

OK, with the access type changed, let?s go ahead and save the file. We do not have to edit this any more then this. 

Now calling a web service is a little different then invoking the component locally. Here is how we would call the method ?ReturnFirstName? as a web service:

<CFINVOKE webservice="http://127.0.0.1/tutorials/cfctutor.cfc?WSDL" method="ReturnFirstName" returnvariable="foo">
    <CFINVOKEARGUMENT name=
"LastName" value="Duck">
</CFINVOKE>


Now you will notice that we removed the argument ?component? and replaced it with ?webservice?. I am calling this component on my local machine, which it resides at http://127.0.0.1/tutorials/cfctutor.cfc, so yours may be different. You must append the web service with ??WSDL?, this is very important. 

So now my saved page that invokes these components looks like this when completed:

<CFINVOKE webservice="http://127.0.0.1/tutorials/cfctutor.cfc?WSDL" method="ReturnFirstName" returnvariable="foo">
    <CFINVOKEARGUMENT name=
"LastName" value="Duck">
</CFINVOKE>

<CFOUTPUT>
   
#foo#<BR>
</CFOUTPUT>

<CFINVOKE webservice=
"http://127.0.0.1/tutorials/cfctutor.cfc?WSDL" method="GetAllEmployeeData" returnvariable="foo2">
</CFINVOKE>

<CFOUTPUT query="foo2">
  
#first_name# #last_name# #salary#<BR>
</CFOUTPUT>


Simple enough. Now you know how to work with components as well as web services, so go out there and have some fun! These examples are not much use in a real world environment, but it does give you a foundation that will help you better understand web services. Let me also suggest a great website in which you can find web services that others have written that you may use in your applications. 

Just point your browser to http://www.xmethods.net
You can get lost in there, I have many times. If you write a useful web service, please submit it to XMethods.net.

Also, check out my website at http://www.tinetics.com for some useful web services and tags as well. Have fun coding!

All ColdFusion Tutorials By Author: Robert Bailey
Download the EasyCFM.COM Browser Toolbar!