Using ColdFusion components to define data types for web services

ColdFusion lets you define components that contain only properties. Once defined, you can use components to define data types for web services. The following code defines a component in the file address.cfc that contains properties that represent a street address:

<cfcomponent> 
    <cfproperty name="AddrNumber" type="numeric"> 
    <cfproperty name="Street" type="string"> 
    <cfproperty name="City" type="string"> 
    <cfproperty name="State" type="string"> 
    <cfproperty name="Country" type="string"> 
</cfcomponent>

The following code defines a component in the filename.cfc that defines first and last name properties:

<cfcomponent> 
    <cfproperty name="Firstname" type="string"> 
    <cfproperty name="Lastname" type="string"> 
</cfcomponent>

You can then use address and name to define data types in a ColdFusion component created to publish a web service, as the following example shows:

<cfcomponent> 
    <cffunction  
        name="echoName" returnType="name" access="remote" output="false"> 
            <cfargument name="input" type="name"> 
            <cfreturn #arguments.input#> 
    </cffunction> 
 
    <cffunction  
        name="echoAddress" returnType="address" access="remote" output="false"> 
            <cfargument name="input" type="address"> 
            <cfreturn #arguments.input#> 
    </cffunction> 
</cfcomponent>
Note: If the component files are not in a directory under your web root, create a web server mapping to the directory that contains them. You cannot use ColdFusion mappings to access web services.

The WSDL file for the web service contains data definitions for the complex types name and address. Each definition consists of the elements that define the type as specified in the ColdFusion component file for that type. For example, the following example shows the definition for name:

<complexType name="name"> 
     <sequence> 
       <element name="firstname" nillable="true" type="soapenc:string"/> 
       <element name="lastname" nillable="true" type="soapenc:string"/> 
     </sequence> 
</complexType>

You can also specify an array of CFCs in the returnType attribute, as the following example shows:

<cfcomponent> 
    <cffunction  
    name="allNames" returnType="name[]" access="remote" output="false"> 
    <cfset var returnarray = ArrayNew(1)> 
    <cfset var temp = ""> 
    <cfquery name="empinfo" datasource="cfdocexamples"> 
     SELECT firstname, lastname 
     FROM employee 
    </cfquery> 
    <cfloop query="empinfo" > 
          <cfobject component="name" name="tempname"> 
          <cfset tempname.Firstname = #empinfo.firstname#> 
          <cfset tempname.Lastname = #empinfo.lastname#> 
          <cfset temp = ArrayAppend(returnarray, tempname)> 
        </cfloop> 
        <cfreturn returnarray> 
    </cffunction> 
</cfcomponent>

When you invoke the web service, it returns an array of CFCs. Access the properties in the CFC by using dot notation, as the following example shows:

<cfinvoke webservice ="http://localhost:8500/ws/cfcarray.cfc?wsdl" 
    method ="allNames" 
    returnVariable="thearray"> 
 
<cfif IsArray(thearray)> 
<h1>loop through the employees</h1> 
<p>thearray has <cfoutput>#ArrayLen(thearray)#</cfoutput> elements.</p> 
<cfloop index="i" from="1" to="#ArrayLen(thearray)#"> 
    <cfoutput>#thearray[i].firstname#, #thearray[i].lastname# </cfoutput><br> 
</cfloop> 
<cfelse> 
     <h1>Error: thearray is not an array</h1> 
</cfif>