Showing posts with label railo. Show all posts
Showing posts with label railo. Show all posts

22 July 2014

REST Web Services - Part 1 - CFML

Dammit Adam! If there's one thing I hate more than learning its being inspired to learn!

Last week Adam Cameron got me thinking about REST Web Services, he challenged his readers, what is the best language for building them. Well I had a few thoughts which I shared. Basically it depends which language the developer in question is most comfortable in, and which environment is most accessible. In my time I've been lucky enough to be paid to work in a lot of languages and a lot of environments, so I thought I’d do a quick re-cap of a few languages and maybe even attempt a few which I've never learnt. How long it takes before my patience and time run out, we’ll see :)


My environment will be mostly Ubuntu as that’s what I run at home these days, and I’m too poor to run a server. However if I make it on to Microsoft development I’m anticipating switching to Windows 7. As for the REST services themselves I’m going for Keep It Simple Stupid here, basic proof of concept stuff. I want a GET and a POST method and that’s about it. Also I’m largely ignoring security for the time being.


First up is ColdFusion.
I’ve spent many of my years being paid as a CFML developer and I’m most comfortable with it. I should be able to knock out some REST web services here pretty quick. As much as I like CFML, Rest in CF is a pain in the neck. To me the syntax is not intuitive, mistakes are difficult to pin point, debugging is very difficult and testing a nightmare. Someone reminded me of an add on called Taffy, which is a REST framework for CF. I've never encountered Taffy myself, so I'm hopeful and excited for the challenge.


First I install Railo express, not rocket science, suffice to say it works and in just two minutes I’m running a test cfm page. (Awesome job Railo guys!)


Now I need to get Taffy running. So I download the zip file and extract it. Loosely skimming through the docs I see I can just drop the taffy folder into my Railo root. Awesome, drag and drop, ok, now what? OK So back to the docs, I’ve got to add an extension to my Application.cfc and create a hello.cfc. So not that drag and drop then. After about thirty minutes fiddling around with resources directories and tweaking Application.cfc files I’ve finally got the Taffy welcome page working properly. What held me up was *not* using the Application.cfc supplied in the docs but instead borrowing the one from the help folder. My setup is as such:


Railo/webapps/ROOT/hiya
-- Application.cfc (see below)
-- index.cfm (empty cfm file)
Railo/webapps/ROOT/hiya/resources
-- hello.cfc (my REST webservices)


I now have Taffy running with Railo. This is awesome, the format for web services is pretty good, I don't need to endlessly update Railo or my application config, it just works. The test bed is the best thing, I love the bootstrap layout and it makes it so simple and easy to test. I've put a screenshot down the bottom.

Here's some code.


My Application.cfc is:

<cfcomponent extends="taffy.core.api">
    <cfscript>

        this.name = hash(getCurrentTemplatePath());

        variables.framework = {};
        variables.framework.debugKey = "debug";
        variables.framework.reloadKey = "reload";
        variables.framework.reloadPassword = "true";
        variables.framework.representationClass = "taffy.core.genericRepresentation";
        variables.framework.returnExceptionsAsJson = true;

        function onApplicationStart(){
            return super.onApplicationStart();
        }

        function onRequestStart(TARGETPATH){
            return super.onRequestStart(TARGETPATH);
        }

        // this function is called after the request has been parsed and all request details are known
        function onTaffyRequest(verb, cfc, requestArguments, mimeExt){
            // this would be a good place for you to check API key validity and other non-resource-specific validation
            return true;
        }

    </cfscript>
</cfcomponent>




Finally the important bit here are my web services (hello.cfc):

component extends="taffy.core.resource" taffy_uri="/hello" {

     function get(){
        return representationOf(['all your base are belong to me. :)']);
    }
    
    function post(String name){
        return representationOf(['Nice to meet you ' & name]);
    }

 }
And CFML is done. All this, including install of Railo and Taffy took me around an hour.

If you’re Adam Tuttle, congratulations Taffy is a fantastic product and I'm very impressed. The ease at which I can deploy web services and most importantly test them is now fantastic. I don’t need to create silly little html forms or anything, it’s all built in. This is genius.  If I may offer my two cents here, you've got a little work to do on the docs. Especially the initial deployment. It’s gotta be step by step built for idiots like me. If I can’t make it work quickly, I lose interest. That aside you should be really proud.



11 January 2014

The death of noisypix.com

Some time ago I noticed every one of my (technologically challenged) parent's photos were taken at around eight million gigabytes. Backing them up was becoming a pain and taking up a huge amount of space! So I created noisypix, a simple website to upload photos and images too and be provided in return with a smaller shrunk down file which was more reasonable to maintain.

The core of the project was Coldfusion and I already knew photo manipulation was quite simple using
<cfimage>
The exciting part of the project for me was going to be some HTML 5 goodness tucked in with some bootstrap, jquery and jquery filedrop.

Sadly time has passed and I've moved on to other things. Noisypix sits on a linux box with a copy of railo making it all tick. The problem being it costs me money! Not a huge amount but some, and I'm trying to cut back. Plus by the looks of Google Analytics, hardly anyone uses it!

So I've come to the painful decision to kill my linux box and let noisypix out into the wild. I'm going to open source it, post it on github and see what the world does with it. I doubt much will happen but I hope someone one day will learn something from it.

So sometime in February I'll be pulling the plug. If you'd like to check out my code and see what you think, or perhaps even improve and host it yourself, you're most welcome too.

https://github.com/jimbo1299/noisypix

10 June 2013

CFML REST webservices with Railo

I've been doing a lot of REST web services with CFML and Railo lately and wanted to write up my experiences in case it helps.

First you need to setup Railo with your webservice cfc:
http://www.getrailo.org/index.cfm/whats-up/railo-40-released/features/rest-services/

Second you need to create and configure your cfc:
<cfcomponent rest="true" restpath="/hello">

The restpath provides the step in your URL from which your service is accessed. A normal REST webservice is pretty straightforward. Ensure your method is set to access="remote" and add in httpMethod and a restPath param to the cffunction.
<cffunction name="getmuppets" access="remote" httpmethod="GET" restpath="/getmuppets">

The restpath identifies the url structure you'll use to access the webservice.
The httpmethod tells the webservice if it should respond to GET/POST/PUT etc methods. These methods are defined and talked about more in REST definitions: http://en.wikipedia.org/wiki/Representational_state_transfer#Vocabulary_re-use_vs._its_arbitrary_extension:_HTTP_and_SOAP

Returning data is fairly standard, but if you want to return JSON then you might want to look at my previous blog post.

I've found that unlike much of CFML REST is case sensitive, so its a good idea to make everything lowercase.

This should be enough to get you going, but pretty soon you'll need to add arguments. So lets have a quick look at REST arguments. Lets assume for now we're just interested in a GET request.

You add your cfargument as your normally would, but you also need a param called restArgSource.

<cfargument name="intage"    type="numeric"    restArgSource="Path">

Your new method would look like this:
    <cffunction name="getmuppets" access="remote" produces="application/json" httpmethod="GET" restpath="/getmuppets/intage/{intage}/strsex/{strsex}/">
        <cfargument name="intage"    type="numeric"    restArgSource="Path">
        <cfargument name="strsex"    type="string"    restArgSource="Path">
        
        .....
    </cffunction>

Pay particular attention to how the restpath needs to be updated to match the new arguments. We're using restArgSource set to path, which means your url needs to provide those arguments. Here's an example URL:
http://localhost/rest/demo/hello/getmuppets/intage/30/strsex/male
Each step in the URL is a piece of the puzzle.

There are a few types that restArgSource accepts:
  • Path
  • Query
  • Matrix
  • Cookie / Header
  •  Form
Query is pretty straightforward, instead of using path (as above) you can just get your arguments from the query scope, i.e. ?strage=30. Form is when an argument comes from the FORM scope and you'd normally only use this for post and put httpMethods.
For a full explanation of these types, this article provides a good explanation:
http://www.adobe.com/devnet/coldfusion/articles/restful-web-services.html

That's it, you should be ready to write your own. Best of luck!







30 May 2013

Railo Rest JSON Web Service


So I've been writing lots of REST web services lately with Railo 4.0 and noticed a strange issue / feature when returning json.

So I write me a nice little function and I think everything will work with a little CFML magic:

    <cffunction name="getmuppets" access="remote" returntype="string" httpmethod="GET" restpath="/getmuppets">
        <cfscript>
            var arrMuppets    = [
                {name = "kermit", age = 20},
                {name = "fuzzy", age = 30},
                {name = "animal", age = 40}
            ];
            
            return serializeJson(arrMuppets)
        </cfscript>
    </cffunction>


All good? No :( The json is fine when you call the function locally, but when you call it as a rest webservice all the double quotes get escaped. Which renders it invalid json and is not much use for anything.
"[{\"age\":20,\"name\":\"kermit\"},{\"age\":30,\"name\":\"fuzzy\"},{\"age\":40,\"name\":\"animal\"}]"


So I eventually figured out you've got to change the headers and content returned by the function.
    <cffunction name="getmuppets" access="remote" produces="application/json" httpmethod="GET" restpath="/getmuppets">
        <cfscript>
            var arrMuppets    = [
                {name = "kermit", age = 20},
                {name = "fuzzy", age = 30},
                {name = "animal", age = 40}
            ];
            
            response    = {
                status        = 200,
                headers        = {},
                content        = serializeJson(arrMuppets)
            };
        
            restSetResponse(response);
        </cfscript>
    </cffunction>

Once you do all that, you get valid json:


[{"age":20,"name":"kermit"},{"age":30,"name":"fuzzy"},{"age":40,"name":"animal"}]

13 May 2012

ColdFusion Railo deployment with Jelastic

I thought I'd try one of the cloud java hosting platforms out there and I must say I'm delighted I did. I wanted to start up a Jelastic instance and throw Railo on it and see how it worked out.

First up sign in is super simple, just your email and thats all you need. The user interface is clean, powerful and incredibly simple. With simple drop downs to create your environment and configure the number of instances etc that you need. In just a few minutes you can be up and running.
So i chose Tomcat 6. I did initally try Tomcat 7 but apparently they have a few problems with 7 at the moment. Not to worry 6 is fine. Deploy your environment and then wait for it to be deployed. This takes just a minute or so while they build your instance.

Then down at the bottom you'll see the deployment manager tab, under that you should see upload. You'll need to upload your Railo.war you can upload one you've downloaded, or I believe, upload direct from www.getrailo.org:

Once you've uploaded the .war file, you need to deploy it. Simple, still in the deployment manager tab, click on the box dropdown and click deploy. It'll ask you to confirm "ROOT" as the context, but root is fine. Once this is done you should be able to click the "launch in browser" button and see the railo admin show.

That's it, you're basically done. I expect you want your own application to run, but that's just as easy. If you click on the spanner / config option next to Tomcat 6 a settings tab will open and you can tweak the tomcat settings. Expand webapps and root. This is your application home, you can delete everything in there except for the WEB-INF folder. Then upload your cfm files and you're done!

I think this is a brilliant hosting environment and so brethlessly simple I'm very impressed.