Wednesday 29 February 2012

Registering a REST application in ColdFusion10



<- Previous Contents Next ->



PART-II
Tutorial on REST: Registering a REST application



Regitsering a REST application
  1. To access any REST resource you need to register an application either through admin or using restInitApplication().
  2. Registering REST application is required because ColdFusion scans for all the REST resources present in directory you registered
  3. It is also important for you to know that you CAN NOT repeat 'restpath' for one and more resources. That is why it is a better option to create multiple apps, so that you can repeat the restpath in different applications as per your need
  4. You should also know that change in any resource(REST cfc) of your application will need a refresh in applcation. You can refresh from Administrator or using restInitApplication()


Using restInitApplication(): You can register as well as refresh an application using this method

This function takes three attributes: restInitApplication(dir_path, mapping_name, default)
    • dir_path: This is absolute path of the directory where you have plcaed your REST cfc.
    • mapping_name: This name can be anything. But keep in mind that this name will be used URL to call any of the resources in this application. Also note that this is an optional attribute. If this attribute is not present then ColdFusion will try to pick this name from Application.cfc(this.name) applicable to this directory.
    • default: You can get rid of the mapping_name in URL. To do so you can set any one of the application as default. I will discuss/explain this later with an example.
  1. If there is no error thrown, means your application has been registered successfully, so its always better to catch the error using cfcatch block
  2. If there is already an application registered with the mapping_name and the dir_path you gave, then this function will REFRESH already registered app.
  3. But if you will try to register another directory with already registered mapping name, you will get an error


Using Administrator: You can also register an application using Administrator
  1. Go to Admin -> DATA & Services -> REST services
  2. Root Path: Browse the directory which you want to register as REST application
  3. Service Mapping: Give the name of your mapping. This name will be used in URL to call any of the resource present in this application. This is optional. If not given, ColdFusion will try to search for name in Application.cfc(this.name) applicable to that directory.
  4. default: You can get rid of the mapping_name in URL. To do so you can set any one of the application as default. I will discuss/explain this later with an example


Application outside webroot
  1. You can also register a directory as REST application which is not present in your webroot
  2. To do so you have to add a mapping for that directory in ColdFusion
  3. Then you can register using the absolute path or also using that mapping instead of absolute path.



Default application:

If you really do not like to use the application mapping name(IIT - example from previous chapter) for you REST services, there is an option available to do that. But I will personally recommend that if you are publishing your REST services in production, then you should use application mapping name to avoid conflicts and for better management.

To get rid of application name, all you need to do is, make that application as default. There are two ways to do it.
  1. Go to Administrator->REST Services page, edit that application, check the checkbox saying default and update it.
  2. Use below given code if you do not like to go to Admin.
<cfset restInitApplication(absolute_path, mapping_name, "default")>

This will set your application as default and to call your resource you need to hit this URL - "http://localhost:8500/rest/restpath" where restpath is the restpath of your resource.


Few points to remember using default:


Default application is given last preference when you call some resource. Let's say you have a resource with restpath: "one/two" in your default application and you have a resource: "two" in your application named as "one".

  1. So on calling this url: "http://127.0.0.1:8500/rest/one/two", resource with restpath: "two" will be served from application: "one". But if application: "one" is not present then resource "one/two" will be served from default application.
  2. On calling this url: "http://127.0.0.1:8500/rest/one/" (notice a forward slash in the end of url), you will get resource not found, because there is no resource with restpath: "/" in application: "one".
  3. On calling this url: "http://127.0.0.1:8500/rest/one", it will search for resource: "one" in default application because url doesn't has a forward-slash after "one".
There can only be one default application at a time.


Refresh Application:


Once you have registered your application, you might want to change few things in your resources and want to services to reflect the effect. But there is a small hindrance in that. The time you register an application, ColdFusion loads the resources present in that application in memory, so if you are making some changes in you application, you need to tell ColdFusion in some way to refresh the application so that it can reflect the changes.
To achieve this there is a concept of refreshing an application. This can be done in two ways. One is from Administrator-REST Services page you can refresh whichever application you want. But if you want to do it right away from you code, you can use restInitApplication() function.
The same function for registering an application is also used for refreshing an application. If you are calling this function for some application but that application is already registered, then it will refresh it. So the trick is very simple. If application is not registered then restInitApplication() will register it, whereas if it is registered already, then it will refresh it.
For refreshing a default application you need not pass the third attribute("default") but for registering you need to.

Please note that using this function is not recommended in Application.cfc, it might break things. You may use this function in any cfm.



Role of Application.cfc:


If you have Application.cfc in the directory you want to register, then there are few things you might want to know.

  1. this.name - If application name is given in application.cfc, then while registering the application mapping name becomes optional. If you will not give application mapping name then your application will be registered using the name given in application.cfc
  2. this.restsettings.skipcfcwitherror - This is a boolean attribute. Usually if there some compilation error in any of your REST enabled cfc, then while registering you will get an error and you application will not be registered. But if this attribute is true, then even if there are errors in some cfc's, the rest of the cfc's will be published and your application will be registered successfully. Please note that if this attribute is true and all the cfc's have error then error will be thrown that no rest resource found.
  3. this.restsettings.cfclocation - you can give comma separated list of the directory path in this attribute. While registering or refreshing an application ColdFusion will search for all the rest enabled cfc's in these directories too. Please note that in this case, cfc's in current folder will not be considered. If you want to include present directory too, you need to give value something like this: this.restsettings.cfclocation = "/myfolder, ." (notice a dot after myfolder, to include present directory)

Update/Delete an application:

  1. To update already registered application you can go to administrator or you can use same function restInitApplication(). Lets say there is an application with path as "/myfolder" and mapping name as "app1". Now if you call this function: restInitApplication("/myfolder", "app2"), your application registered with "app1" will get updated to "app2".
  2. Though for registration/refreshing/updation same method was used but fortunately there is a separate method for deleting the REST application :) restDeleteApplication(absolute_path). You just need to pass the absolute path of the application registered to delete it.


That will be enough for registering/updating/refreshing the REST applications. I guess so ;)


<- Previous Contents Next ->



Thanks,
Milan.

Tuesday 21 February 2012

Tutorial on RESTful services in ColdFusion



<- Previous Contents Next ->



Tutorial on REST: Introduction

Much awaited ColdFusion10(Zeus) is out with many new, interesting and challenging features. And REST is one of them. So all the developers out there who wants to switch to REST services from SOAP based web services, get your hands on ColdFusion10 Public Beta now and start with REST right away.

This tutorial is like a roller-coaster ride for REST services in ColdFusion10, which will quickly get you started with simple basics and easy examples and also it will cover all the complex techniques of this feature.


Tutorial on REST: Contents

For now to get you started here are initial few Parts, will be updating more with time.

  1. Part-I : Getting Started
  2. Part-II: Registering a REST application
  3. Part-III: First REST Resource(cfc)



<- Previous Contents Next ->


Thanks,
Milan.

Getting Started with REST in ColdFusion 10



<- Previous Contents Next ->



PART-I

Tutorial on REST: Getting Started:

Background: REST services are a kind of web services which use http protocol behind the scenes. Geeks familiar with SOAP based web services must be thinking, Is this really possible (if they don't already know about REST architecture yet)? Yes, REST services uses HTTP architecture to get the work done and same way ColdFusion10 has beautifully used its component(cfc) to publish the REST services and cfhttp tags to consume them. For more information on REST architecture please go through this link.

Note - for simpler understanding, throughout the tutorial I will consider that ColdFusion is installed at "C:\ColdFusion10\" with webroot at "C:\ColdFusion10\cfusion\wwwroot\" and is running on port "8500".

Publishing
  1. After installing ColdFusion10 and setting the webroot(either through standalone or using webserver like IIS or Apache), first step required to setup REST is write a REST enabled cfc in some folder in webroot.
  2. Create a directory named "restApp" in webroot of ColdFusion. You can name this directory whatever you want to as this is just for your reference.
  3. Create a cfc named as "studentHandler.cfc". You can name this cfc as anything you want. Your REST service users will not use this name untill and unless you are mentioning "restpath" at component level in your cfc. I will come to this point later
Paste code given below in this studentHandler.cfc



For those who prefers to stay independent of Administrator
  1. Just call this function from any cfm.
<cfset restInitApplication("C:\ColdFusion10\cfusion\wwwroot\restApp","IIT")>
  1. First argument to "restInitApplication" function is the absolute path where you have placed your REST component(studentHandler.cfc) and second argument is the name from which you will publish your REST application. You can give your relevant Organization name in second argument.
  2. If you didn't got any error after running this funtion, it means your application is registered successfully. That's it, first REST application published.


For those who prefers to use ColdFusion Administrator page (http://127.0.0.1/8500/CFIDE/administrator/index.cfm)
  1. After saving this file go to Administrator --> REST services page
  2. In Path text box give the absolute path till directory "restApp". In this example it will be "C:\ColdFusion10\cfusion\wwwroot\restApp"
  3. In mapping text box give some logical name for the REST application you going to create, let's say "IIT". You can give your relevant Organization name. This name will be used by users in the URL
  4. Hit register, and there you go. First REST application published.

Behind the scenes/tricks:
(these are quick tricks to know, but will covered in later parts of tutorial)
  1. When you hit 'restInitApplication()' function, ColdFusion registers your application. You can also see that application later on in Administrator REST Services page.
  2. When you create a REST enabled component in your webroot and register that folder, ColdFusion consider that folder as one REST application. 
  3. As many resources(cfc or functions in cfc) as you want, can be created in one application but the only thing is that restpath for these resources should not conflict with each other.
  4. Nested REST applications are not allowed.
  5. You can keep your application outside webroot too. For this you need to add a mapping for a directory in Administrator and then you can register this directory using absolute path or mapping(the name with which you added a mapping), both will work. 
  6. Application names are case-INsensitive.
  7. Calling restInitApplication() for already registered application actually REFRESH that application.
  8. Calling restInitApplication() with different mapping name(second attribute) will update the registered application with absolute path(first argument), with new name.
  9. If you want to skip giving application mapping name, you can use 'default' feature, you can set an application as default and while consuming you can call a resource without giving mapping name in URL. Keep checking  this area for this point. I will write separate post for this.
  10. While registering an application, if application mapping name is not given, then it picks the same in the directory's(one you are trying to register) Application.cfc(this.name).




Consuming


As you saw it was damn easy to publish a REST service but consuming is a lot Easier than that. All you need to do is hit this URL: http://127.0.0.1:8500/rest/IIT/student

I hope you got the response as "foo", because this is what we returned from studentHandler.cfc in function "getMethod".

How URL works:

  1. http://127.0.0.1:8500/ - This is a equivalent to protocol://ip:port of your server in which the REST resource is present.
  2. /rest/ - This string 'rest' in URL is necessary to tell ColdFusion that this is a REST call. You can change this 'rest' in server.xml
  3. /IIT/ - this is the mapping_name from which you registered your REST application.
  4. /student/ - This is the restpath of the resource you defined in studentHandler.cfc
Consuming in cfm:
  1. For consuming REST services in cfm file you need to call the above URL using cfhttp tag.
  2. Run the code given below.
  3. Just take care that the method in cfhttp call should be 'get', as it has to match the 'httpmethod' given in cfc.

How this works
  1. By looking at the URL, ColdFusion gets to know that this is a REST call and it also gets to know that for which application this call has been made because of the mapping name present in URL('IIT' in this example)
  2. Once we know that which application it is, we can easily get to know that which resource(cfc) has been called, because a cfc has a restpath which has to be unique for every appliction and this restpath is also included in URL('student' in this example)
  3. Once we get to know that which cfc has been called, we match the httpmethod of cffunction with the method of the request(cfhttp). In this example for both of them we mentioned 'GET'. So by calling a get request on this resource we hit the function whose httpmethod is 'get'.
  4. Once we know which cffunction to call, its very easy to return the response.
  5. There is also a possibility to have more than one function in same resource with different httpmethod, So it's quite possible that on calling same URL with get request you might hit one function whereas calling 'put' you might hit another. Details about this will be covered later.

Note:Application name(mapping name from which you registered your REST app) is case IN-sensitive.

<- Previous Contents Next ->



Thanks,
Milan.

Friday 10 February 2012

Equate arrays, structs, query or possible combination of three


Have you ever felt need to compare two arrays in ColdFusion or comparing two structs or may be two queries. If you are reading this, I am sure you felt at some point and if not, you can still read on :)

We use arrays, structs and queries so regularly in ColdFusion that at some point or the other we have to compare them and we dump it to check if its coming fine. Dump is such a powerful tag in ColdFusion that you should use it but what if you want to write a script to check that. Ahhh... cfdump cannot be used there right.

Well not to worry, I have written a code, in fact to be precise I have modified a script (courtesy-cflib.org) which will allow you to compare arrays or structs or queries. Even if you have complex objects like array of struct or array inside struct or query in array of struct or whatever possiblity you can think of these three, you can easily compare using three simple functions: arrayCompare(leftarray, rightarray), structCompare(leftStruct, rightStruct), queryCompare(leftQuery, rightQuery).

I will post complete code n the end, you can save that in .cfm file and call the functions at your will. So it's like if you have two comparable variabes:array of structs, you just need to pass both of them to arrayCompare() OR if you have complex structs having array or query inside you need to call arrayStruct. Handling of array, struct or query present inside your variable will be automatically taken care of.

If both the variables passed by you are equal then this will return a boolean true else false. Find comments inline to understand the code.

So go ahead, you this file, call functions and compare your complex variables at ease.

Click below given link to see the code:



This code is also available at cflib.org but I have modified it according to the need, so it might not be the same. If you are looking for a complete set of three features(array, struct, query compare) this file is perfect for you.

Share if you feel its worth it. Comments will be a +1.

-Milan Chandna

Saturday 4 February 2012

Continue in cfloop


Have you ever used continue in cfloop without cfcontinue/cfbreak.

Check this code:

Here I have a <cfloop> which runs 10 times for value of 'i'. I want to implement continue tag if the 'i' is an even no. To achieve that check if the no.is even and if it is, I throw a custom error.

The good thing is that you can always catch this error. So Catch this error before closing </cfloop> tag. Though you can add some code over there also but it totally depends on you. For a normal continue you need not add anything in <cfcatch> block. As expected this thrown error wil be caugth in <cfcatch> and it will proceed for next iteration in <cfloop>, without any error. And this is how it behaved as continue.

So all in all you need to remember that

  • instead of continue you can throw a custom error
  • catch this error in the end (before closing </cfloop> tag)
  • Do nothing in <cfcatch> tag (though its your wish but its not necessary)
  • close </cfloop> tag.

Hope you got this.
Cheers!!!