Web Services RESTlet support

Any CFC can be made into a remote RESTlet service endpoint by simply enabling the access="remote" attribute on a function within a component. Once enabled, this function can be called directly using standard HTTP protocols without first binding it to a CFML page. Even though it is not bound to a specific CFML page, it still obeys the rules of a CFML application in that the Application.cfc/.cfm will still be sought and run prior to any call.

<cfcomponent>
  <!--- assume this is saved @ /rpc/mycfc.cfc --->

  <cffunction name="run" access="remote" returntype="string">
    <cfreturn "from a remote">
  </cffunction>

</cfcomponent>

This method is now available for consumption through a simple RESTlet call using the following endpoint:

  • http://myhost.com/rpc/mycfc.cfc?method=run

The RESTlet call is most useful for Javascript based applications, allowing you to consume and trigger CFC from within any web page running on your server. A CFC called in this manner can have a number of different return formats using the returnformat="wddx|plain|json|jsonp" attribute of a function.

Passing parameters to a RESTlet endpoint

The only pre-defined parameter that must be present in every RESTlet call is the method which designates which function within the CFC will be invoked. Any other parameter passed in the URI string is assumed to be an argument to the function.

There are two options for retreiving the parameters within the CFC that is acting as the RESTlet endpoint.

  • Use the standard url scope
  • Define the CFARGUMENT for each parameter

The advantage of using the CFARGUMENT technique allows you to keep your CFC object generic as possible, allowing it to be used internally within your application without having to setup the url scope to simulate a remote call. The main selling point, is that it allows your CFC to advertise the parameters it requires and if not present, the engine will do all the work for you in terms of validation and defaulting.

<cfcomponent>

  <cffunction name="run" access="remote" returntype="string">
    <cfargument name="param1" required="true" />
    <cfargument name="param2" required="false" default="true" />
    <cfreturn arguments.param1 & arguments.param2>
  </cffunction>

</cfcomponent>

Having defined your parameters/arguments for your CFC function, this then allows you to pass in data to the CFC using the following syntax.

  • http://myhost.com/rpc/mycfc.cfc?method=run&param1=TestParam

Returning rich objects back

Web services are usually designed to return raw data, and leave the formatting or UI to some other process. This is the core reason to offer Web Services to your application, freeing up your data, permits 3rd parties to innovate with your service. CFC's called in this manner are not limited to returning simple plain text - it can manage rich objects (structures, arrays, queries) using WDDX or JSON.

The good news is that you do not have to manually encode the output; the underlying OpenBD engine will do all the transformations for you. All you have to do is to simply set the returnformat="json|plain|wddx|jsonp" attribute of the function in question, and the engine will do everything for you (note only simple types can be returned if PLAIN|JSONP)

<cfcomponent>

  <cffunction name="run" access="remote" returntype="struct" returnformat="json">
    <cfargument name="param1" required="true" />
    <cfargument name="param2" required="false" default="true" />

    <cfset myStruct = StructNew()>
    <cfset myStruct.param1 = arguments.param1>

    <cfreturn myStruct>
  </cffunction>

</cfcomponent>

When invoked internally by another CFC or page this function will return a standard struct object. If, however, called via a RESTlet remote call, this function will return the same structure but encoded as JSON text {"param1":"TestParam"}.

The remote caller can override the return format, by specifying the desired encoding method using __BDRETURNFORMAT in the calling parameter. For example, to encode the structure as an XML packet you could use:

  • http://myhost.com/rpc/mycfc.cfc?method=run&param1=TestParam&__BDRETURNFORMAT=wddx

Pre-defined parameters

Remotely calling CFC's can support a number of other directives that lets the calling party control its execution.

  • method=myFunction
    This determines which function of the CFC will be called (required)
  • __BDRETURNFORMAT=wddx|plain|json|jsonp
    This determines how the function will format its return content (note only simple types can be returned if PLAIN|JSONP).
  • __BDNODEBUG
    If this parameter exists, any error the CFC throws will be surpressed. This stops the full error stack page to be sent to the remote caller.
  • __BDJSONCASE
    If this parameter exists and the return format is JSON, then this controls the case of the keys of the resulting JSON (lower, upper or maintain [default])
  • __BDQUERYFORMAT=column|row
    If the CFC is returning back a CFML Query object, then this controls how the data is represented, either as an array of rows, or array of columns.

Cross-Domain Support

RESTlet calls are very powerful mechanisms for providing a very simple straight forward web service facility to your applications. Any server will be able to talk to your endpoint and interact with your application.

However, what if you wish your services to be consumed by a Javascript function outside of your own domain? Cross-domain scripting will prevent this. So how do the likes of delicious.com offer such Javascript integrations for their services?

You achieve this by using JSONP (JSON with Padding) and this lets you achieve cross-domain data fetching. Fortunately, OpenBD supports this protocol straight out of the box. Discover about JSONP support.