Skip to main content

ColdFusion 10: RESTful WebServices in ColdFusion - Introduction

In ColdFusion 10, support for creating and publishing REST services has been added. The ColdFusion components can now be made available as REST services and these services can be consumed by various clients. REST stands for Representational State Transfer. It is an architectural style which is based on web standards and HTTP protocol. The idea here is to use HTTP protocol instead of complex mechanisms such as CORBA, RPC or SOAP to connect between the machines. In fact, the World Wide Web which is based on HTTP can be viewed as a REST based architecture.

REST Architectural principles:

A REST based application follows some architectural principles:

  1. Resource Identification: In a REST based architecture everything is a resource. Each of these resources should be identified with a URI.  In ColdFusion, the functions are identified as resources, each of these resources can then be invoked using an URI.
  2. Uniform and constrained interface: Every resource in a RESTful application should support HTTP common operations. The resources are manipulated with the HTTP protocol methods – GET, PUT, POST, DELETE.  In ColdFusion, the resources (functions) can be accessed via HTTP and each of these resource support the HTTP verbs. Depending on the verb specified in the request, the corresponding resource would be invoked.
  3. Representation oriented: REST allows resources to have different representation – plain, html, xml, json etc. A client can request a specific representation via the HTTP protocol. HTTP provides a simple content-type negotiation protocol between the client and the server. For example, an AJAX application may need data in JSON format, where as a Java application may need it in XML format.
  4. Stateless communication: In REST, the server doesn’t store the client session data. However, many techniques exist to exchange state information such as URI rewriting, cookies and hidden form fields. Also, for encryption REST can be used on top of HTTPS.

Getting Started with creating REST services

New attributes have been added to cfcomponent, cffunction and cfargument to aid in creating a REST service. Once a component is created it has to be registered with the Administrator and then it can be accessed via a HTTP request.

Creating a RESTful Web Service

cfcomponent:

As mentioned above, functions in a CFC are the resources and are invoked using a HTTP request. To mark a component as a REST service, attributes rest and restpath are provided. The attribute rest is a boolean attribute, if true the component is enabled as a REST service. This is an optional attribute if restpath is specified in cfcomponent tag. The restpath attribute is used to specify the path using which the REST service would be accessed. If restpath is not specified then the path to the CFC would be used in the URI to invoke the service.

<!--- component with attributes rest and restpath ---> <cfcomponent rest="true" restpath="/crudService"> <!--- handle GET request (httpmethod), take argument in restpath(restpath={customerID}), return query data in json format(produces=text/json) ---> <cffunction name="getHandlerJSON" access="remote" httpmethod="GET" restpath="{customerID}" returntype="query" produces="application/json"> <cfargument name="customerID" required="true" restargsource="Path" type="numeric"/> <cfset myQuery = queryNew("id,name", "Integer,varchar", [[1, "Sagar"], [2, "Ganatra"]])> <cfquery dbtype="query" name="resultQuery"> select * from myQuery where id = #arguments.customerID# </cfquery> <cfreturn resultQuery> </cffunction> </cfcomponent>
The function ‘getHandlerJSON’ handles a GET request and accepts an argument customerID. Notice the additional attributes in cffunction tag. The attribute ‘httpmethod’ is used to specify the type of request this function would handle (GET,POST etc,.). Attribute ‘restpath’ is used to specify the path that should be used in the URL, here the path is specified in curly braces as {customerID}. When this type of notation is used it indicates that a value is passed in the URL and the same has to be copied to the functions’ argument. Therefore the name of the argument is same as the one specified in restpath. There are different ways to pass arguments to a REST service, I’ll explain this in my next post.

Complex data types in ColdFusion such as Array, Query, Struct etc, will be serialized to either JSON or XML format. The produces attribute specifies the mime type to which the data returned by the function will be serialized to. There is also an attribute ‘consumes’ that specifies the mime type of data present in the request body.

Coming to the function arguments, the new attribute restargsource specifies the way in which arguments are passed to a rest service. In this example it is path which indicates the argument will passed in the URL path itself. The other possible values include Matrix, Header, Cookie, Form and Query.

Registering a REST Service

There are three ways in which REST services can be registered with the ColdFusion Administrator. You can use the Admin API (functions defined in extensions.cfc), the ColdFusion administrator console or use the restinitApplicaiton function. Using the Admin API and ColdFusion administrator console requires Administrator privileges and therefore would be available only to selected users. The function restInitApplication can be used to register a REST service and doesn’t require Administrator privileges.

restInitApplication(‘Absolute_path’,[‘Service mapping’])

The directory containing CFC files with with either rest=’true’ or with a restpath in the cfcomponent tag should be specified as the first argument. To identify the set of CFCs in a directory the Service mapping has to be provided. This is an optional fied, if there is an Applicaiton.cfc file present in the directory. In which case the Application name would be used to identify the REST services in the directory.

If any changes are made to any of the components in the registered directory then the corresponding service has to be refreshed. Again this can be done in the Administrator or a call to restInitApplication would refresh the registered service.

Accessing a REST service via HTTP

A RESTful Web service can be accessed either by using HTTP or HTTPS.  The URL to access a REST service in ColdFusion follows this format:

http://servername:port/context_path_j2ee/ rest/rest_application_name_or_serverMapping/restpath_or_componentPath/additionalrestPaths/params_ifany/

Here, the context_path_j2ee is applicable only if you have installed ColdFusion as J2EE on any of the Application servers. In which the context path would be cfusion (by default). However, this can be omitted on Standalone installation.

The string ‘rest’ in URL specifies that the request is for a REST service. ColdFusion has a servlet mapping for the same and would direct the request to the servlet that handles REST service. If there is a directory in the server webroot with the same name, then the servlet mapping has to be updated in web.xml file inside wwwroot\WEB-INF directory.

As mentioned earlier, while registering a REST service the application name specified in Applicaiton.cfc file would be used in the URL to access the REST service. If there is no Applicaiton.cfc then the specified service mapping would be used. To access a service specified in the component the restpath for the component has to be specified. However, if the restpath is not specified in the cfcomponent tag then the path to the CFC would be used in URL. Also, the functions defined in component can also have restpath defined and this has to be specified in the URL. If arguments are to be passed in the URL path then the same can also be specified.

In this example, the function ‘getHandlerJSON’, can be accessed using cfhttp:

<cfhttp url="http://localhost:8500/rest/restapp/crudService/1" result="restResult" method="GET"/>

Here restapp is the application name defined in Applicaiton.cfc file. /crudService is the restpath specified in the cfcomponent tag and the numeric 1 is the argument to the REST service. There are various ways in which arguments can be passed to a REST service, I’ll explain this in my next post.

Comments

  1. Sagar...

    Is there any way to avoid having the /rest/restapp/ in the URL?

    ReplyDelete
  2. What he said :-) Would be good if the rest/restapp (or at least the rest/) part could be avoided.

    Also could you show how one would handle a PUT request (fileupload) alongside additional parameters? For example a user wants to PUT an image and also supply a title for it. What would that look like?

    Thanks.

    ReplyDelete
  3. It is possible to have the CFCs in a default directory and call the REST service without referring to application name\service mapping (restapp) in the URL. I'll post this soon.

    ReplyDelete
  4. Andy Matthews Stefan Richter 
    I've made blog post that explains how you can access a REST service without specifying the Application name or Service mapping in URL -  http://www.sagarganatra.com/2012/02/coldfusion-10-accessing-rest-service.html  

    ReplyDelete
  5. I have a working ReST function that output json

    I added produces="text/json" (which is what it was returning already) and it still worked

    I changed it to produces="application/json" and while return status was still 200
    and the mimetype has application/json
    Filecontent contains
    object of java.io.ByteArrayOutputStreamClass Namejava.io.ByteArrayOutputStream
    Am I understanding / using produces correctly?

    Thank you

    ReplyDelete
  6. Can you deserialize the JSON string i.e. deserialize httpresult.filecontent, you should be able to see the JSON string.

    ReplyDelete
  7. Hi, I do not get the difference between a normal web service though a cfc, and forms with GET & POST compared to the new rest service. I need some enlightenment, anybody?

    ReplyDelete
  8. There are many articles already written on SOAP vs REST based services. I've written a series of posts on RESTful services in ColdFusion - 
    http://www.sagarganatra.com/search/label/REST; this should give you a good understanding of the feature.

    ReplyDelete
  9. Hi ..could u suggest me ways to create a xml request/response without the soap envelope?

    ReplyDelete
  10. You just need to change the produces attribute's value to application/xml. This will return the data in xml format. Please see - 
    http://www.sagarganatra.com/2012/02/coldfusion-10-returning-complex-data.html and 
    http://www.sagarganatra.com/2012/02/coldfusion-10-using-http-content.html

    ReplyDelete

Post a Comment

Popular posts from this blog

Adding beforeRender and afterRender functions to a Backbone View

I was working on a Backbone application that updated the DOM when a response was received from the server. In a Backbone View, the initialize method would perform some operations and then call the render method to update the view. This worked fine, however there was scenario where in I wanted to perform some tasks before and after rendering the view. This can be considered as firing an event before and after the function had completed its execution. I found a very simple way to do this with Underscore's wrap method.

De-obfuscating javascript code in Chrome Developer Tools

I had blogged about JavaScript debugging with Chrome Developer Tools  some time back, wherein I have explained how these developer tools can help in debugging javascript code. Today Google Chrome 12 was released and my Chrome browser was updated to this version. As with every release, there have been some improvements made on performance, usability etc,. One feature that stood out for me is the ability to De-obfuscate the javascript code. What is Minification? Minification is the process of removing unnecessary characters such as white spaces, comments, new lines from the source code. These otherwise would be added to make the code more readable. Minifying the source code helps in reducing the file size and thereby reducing the time taken to download the file. This is the reason why most of the popular javascript libraries such as jQuery are minified. A minified jQuery file is of 31 KB in size where as an uncompressed one is about 229 KB. Unfortunately, debugging minified javascript f

On GraphQL and building an application using React Apollo

When I visualize building an application, I would think of using React and Redux on the front-end which talks to a set of RESTful services built with Node and Hapi (or Express). However, over a period of time, I've realized that this approach does not scale well when you add new features to the front-end. For example, consider a page that displays user information along with courses that a user has enrolled in. At a later point, you decide to add a section that displays popular book titles that one can view and purchase. If every entity is considered as a microservice then to get data from three different microservices would require three http  requests to be sent by the front-end app. The performance of the app would degrade with the increase in the number of http requests. I read about GraphQL and knew that it is an ideal way of building an app and I need not look forward to anything else. The GraphQL layer can be viewed as a facade which sits on top of your RESTful services o