Skip to main content

ColdFusion 10: Accessing a REST service without specifying the Application name or Service mapping in URL

In my previous post, I’d explained how REST services can be created, published and accessed in ColdFusion 10. Andy, asked me “Is there any way to avoid having the /rest/restapp/ in the URL?”. In short Yes. ‘rest’ in the URL lets the ColdFusion Server know that the incoming request is for a REST service. As mentioned in my previous post, you can update the servlet mapping defined in web.xml located at cfusion_home\wwwroot\WEB-INF directory. But it can't be avoided. Coming to the ‘restapp’ in the URL which indicates the Application name or the Servlet mapping. It can be removed from the URL by placing the CFCs in a default directory. While registering a REST service in the ColdFusion Administrator, there is an option to set the service as a default service, meaning all the CFCs placed in the directory would not require the Application name or Service mapping to be provided in the URL.

Here’s the REST Services page in ColdFusion Administrator:

RESTServices_CFAdministrator
After providing the directory containing CFCs to be published as REST services, you can set the same as default application. The CFCs found in this directory will not require a mapping to be specified in the URL. One thing to note here is that, there can be only one such directory for the Server.

In the Administrator say you have provided a path to the directory containing a CFC as ‘C:\work\ColdFusion\cf_main\cfusion\wwwroot\restapp\default’ and the CFC contains a function that is to be exposed as a REST service:

<cfcomponent rest="true" restpath="/customerService"> <cffunction name="getRequestHandler" access="remote" returntype="String" httpmethod="GET" produces="text/html" restpath="{name}"> <cfargument name="name" type="string" restargsource="path"/> <cfreturn "<h1>Hello " & name & "</h1>"> </cffunction> </cfcomponent>

Once this CFC has been registered with the Administrator it can be accessed using the URL: http://localhost:8500/rest/customerService/Sagar

Notice the URL now. It has the ‘customerService’ right after ‘rest’. 'customerService' is the restpath defined in the above CFC. There is no Application name or the Service mapping present in the URL.

Comments

  1. It would have been great if there was a way to define the service mapping at the application level. So, I would do:

    this.restServicePath = "/api/";

    and then just call http://[domain]/api/test

    ReplyDelete
  2. @db76faef2a1f4da09dfa3f56b28d3d87 What if there is a directory under the webroot with the name 'api'. How will the server decide which request to execute i.e http://domain/api/test/index.cfm or the REST service.

    The reason why rest is introduced in web.xml file is that the Servlet to execute a REST request will take a different route when compared to other cfm requests.

    ReplyDelete
  3. What will happen now if there is a directory under the webroot with the name 'api'? My guess is it will be ignored. I would think the same can be done at application level instead of Servlet level.

    ReplyDelete
  4. Although I like the idea, I think ignoring one over the other would not be the right decision. In a case there are many such Applications and each of these have a restServicePath that conflicts with a directory name then it wouldn't be right.

    I wonder how that would work in a shared hosting environment.

    ReplyDelete
  5. I agree ignoring one over the other is not the right decision. But, my point is that's probably what CF will do now. ie. if I have a folder called 'rest' in the webroot, it will probably be ignored because the servlet is routing the request as a rest call.

    Doing routing at the application level makes more sense as you can specify where your rest CFCs are (just like ORM cfcs) and then access them based on the path. 

    As you already mentioned, the current way it is setup, will not allow anyone in shared environment to have a url of their choice. 

    ReplyDelete
  6. As mentioned in the post, the server owner\administrator always has an option of changing 'rest' to anything else by updating web.xml file. If there is a directory with name 'rest' then that would be ignored, but that's the only exception. 

    ReplyDelete
  7. Hi Sagar, can you give us an idea/sample how we can securing the new REST services with authentification? Like popular REST API with api-key or username and password.

    ReplyDelete
  8. @roger there are various ways in which you can pass data to a REST service, please read my post on 'Understanding REST parameters' - 
    http://www.sagarganatra.com/2012/02/coldfusion-10-understanding-rest.html . Let me know if this answers your question.

    ReplyDelete

Post a Comment

Popular posts from this blog

Server sent events with HTML5 and ColdFusion

There are several ways to interact with the server apart from the traditional request\response and refresh all protocol. They are polling, long polling, Ajax and Websockets ( pusherapp ). Of all these Ajax and Websockets have been very popular. There is another way to interact with the server such that the server can send notifications to the client using Server Sent Events (SSE) . SSE is a part of HTML5 spec:  http://dev.w3.org/html5/eventsource/

File upload and Progress events with HTML5 XmlHttpRequest Level 2

The XmlHttpRequest Level 2 specification adds several enhancements to the XmlHttpRequest object. Last week I had blogged about cross-origin-requests and how it is different from Flash\Silverlight's approach .  With Level 2 specification one can upload the file to the server by passing the file object to the send method. In this post I'll try to explore uploading file using XmlHttpRequest 2 in conjunction with the progress events. I'll also provide a description on the new HTML5 tag -  progress which can be updated while the file is being uploaded to the server. And of course, some ColdFusion code that will show how the file is accepted and stored on the server directory.

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.