Showing posts with label frameworks. Show all posts
Showing posts with label frameworks. Show all posts

Friday, January 8, 2010

Fundamental Lightwire Bug?

**UPDATE 01/09/10** Peter Bell, the creator of Lightwire, has addressed this issue. You can find his blog post about it here. I've also update this post as well.


This bug seems extremely fundamental to be a real bug so my initial thoughts are that I'm doing something completely wrong. An issue like this would have been discovered by now.


Brian Carr and I were working on some front end development for our project that leverages Quicksilver and Lightwire when we came across an bug in the UI. Whenever a form was submitted that contained form validation errors, it appeared to be returning correctly the first time. However if you were to submit the same form again, we noticed the error messages would continue to duplicate and stack. Initially we thought there was an issue with Quicksilver not configuring the beans correctly or perhaps we tagged our Errors object with a singleton annotation. After some digging into our bean configuration annotations, everything was annotated correctly. 


So next step was to switch our dependency injection provider to ColdSpring, which Quicksilver allows you to do with one line. What happened to our surprise? It worked! The errors were displaying correctly. Ok, so now we know that the issue is Lightwire specific but didn't know whether it was a Quicksilver or Lightwire problem so we dug into Quicksilver's injection provider service for Lightwire. Perhaps we're wiring something incorrectly. After a good amount of investigation we verified Quicksilver was setting configuring beans correctly for Lightwire consumption.


Our next step was to completely bypass Quicksilver altogether. If we can configure these beans using just Lightwire and a scratch pad and still seeing this error then we can safely deduce that it was a problem in Lightwire. So here is what we found...


First, here is the jist of the classes involved. Both are TRANSIENT objects.




Simply, a BusinessServiceResponse has an Error object. For this example, the hashcode member is a unique hash that is attached to each unique instance.


Here is the code that we are using to test:





  1. Line 4 - 14 Configure the two transients - Errors and BusinessServiceResponse
  2. Line 16-20 Configure setter dependency. BusinessServiceResponse has an Errors property to be injected with the Errors transient object.
  3. Line 24-38 On the first iteration we are getting the bean for the first time then displaying the hashcode on the BusinessServiceResponse and the Errors. It's important to note that Errors hashcode is accessed through the BusinessServiceResponse on line 37.
Here are the results:


It appears that errors is being handled as a transient as the hashcode are identical across all three BusinessServiceResponse creations. Now that we know what the problem was, we dug into the Lightwire code. We found the issue in Lightwire.cfc. It loads setter dependencies as singletons by default??? Nooo, can't be.


On line 273, its creating each bean as a singleton. After replacing line 273 with an singleton/transient check like so:


It worked. Let's rerun our tests.


Hashcodes are different meaning now they are transients as well.





*** UPDATE 01/09/10 *** Do NOT use the code I posted as a fix as there has since been an official patch to fix this issue. Grab it from here. Many thanks to Peter Bell and Brian Rinaldi for their help and quick response on this!

Please guys, help me see the light...

Thursday, December 17, 2009

Quicksilver - REST, MVC, AOP in 26 lines of code, 6 annotations and 0 xml.

You read it right. Let's jump right into how the Quicksilver Framework accomplishes this.





Here is the view - getStuff.cfm





And finally, the results when run:




So, how did we just implement MVC?




STEP 1 - Annotate your component with @viewRoot. This is where all your views are stored.
STEP 2 -  Map the uri and http method to your url. You can optionally use the @returnTypeName annotation so when defined, it's value is mapped to the methods return and will be available in the request scope of your view Look at the getStuff.cfm screen cap above..
STEP 3, non-step - Sit back and relax. Watch the goodness of convention over configuration. QS will look in your @viewRoot for a directory named after the controller, in this case SampleService. Then within that directory look for a file whose name matches the method being mapped.


How did we implement AOP?


STEP 1 - Annotate your cross cutting method with @aspect and give it a name.
STEP 2 - Decorate the target method with @preAspects and/or @postAspects annotations. A comma separated list of the aspect names.


So when getStuff() was run, Quicksilver first ran the aspect addRandomStuff(). All in 2, dos, ni steps. Cool eh?


How did we implement REST?


NO STEPS! - You already did when you annotated for MVC.Proof? Lets hit that URL again but leverage Quicksilver's automatic response serialization (of array, structs, queries)  and get back a JSON representation of "stuff" instead of going through MVC. Simply append ".json" to the end of the url, nothing else needs to change. Hit the url with .json and you'll see this:



That's all folks. All of this in 26 lines of code using 6 annotations and 0 xml.

Hope this helped and please hit us up with any questions.

-Micky

Sunday, December 13, 2009

Quicksilver and REST

Let's talk about some REST a la Quicksilver shall we? In my Quicksilver primer post I touched on what it's all about and its automatic dependency injection capabilities. Today we touch on another one of its core features - REST. If you are not familiar with the concept I encourage you to look into first before reading this post.

Let's set the stage. Imagine you built a simple informational design patterns site that explains design patterns. It's been in production for awhile now using OO best practices like service objects to be the intermediary between internal api calls and the data layer. This site has been using Quicksilver because they wanted a powerful flexible framework to one day use AOP and REST in addition to Automatic Dependency Injection just in case they needed to open up their API to other programs. Fast forward to now, they've been getting requests to open up their API via web services. They can use Quicksilver's REST support to do this easily

To understand how QS provides a simple solution to this, let's explore a possible alternative. They could develop soap based web services that consumes their service layer. Not a bad approach, but possibly time consuming and if done incorrectly can also lead to duplicate code since the methods will need to understand how to return json, xml, or a custom format. Also each web service endpoint would be exposed through a cfc - /path/to/webservice/DesignPatterns.cfc?wsdl and call methods off that.  Ugly ugly ugly. Doing it this way is unorganized and resources are all over the place with crud-type methods names - saveThis(), updateThat(), getThis() etc. Get my drift? How does Quicksilver solve this?

Let's dig into the code that we are about to REST'ify.

We've got a design pattern service with one method getCreationalPatterns(), it simply returns an array of strings whose values are pattern names. Here's the code:


Simple enough right?

  • We've got a singleton annotation at the top that tells Quicksilver that this should be handled as a singleton. This is part of automatic dependency injection baby.
  • getCreationalPatterns() simply returns an array. In the real world this could (and should) get as complex as you wanted to, perhaps delegating to a DAO or gateway or even another service but for this example let's KISS.
Good, now take a look at the unit test written for this. Again keeping it simple, let's assert that we are getting five elements back. Using MXUnit, let's write it:



Test passed. Sweet.

Ok so let's now expose this method as a RESTful endpoint that returns a json representation of creational patterns shall we? Let's not create a new component and go through soap based web services, it too much work :) Let's use Quicksilver. How? Use two, count em, two simple annotations in your service object.

  1. @url - this annotation is used to specify your url pattern. 
  2. @httpMethod - possible values are GET, POST, DELETE, PUT. You can use multiple methods separated by commas.
So here's the updated code:



Lines 8-11 baby, that's all you need. Now when I crack open my browser and hit:
http://localhost:8500/learnqs/howtorest/api.cfm/design/patterns/creational.json
We get a json representation like so:


When opened looks like:


See how easy that was? We've just opened up our API via restful web services to our consumers quickly and easily.When this URI is called from an ajax request, consumers are free to use the json representation of the creational patterns however they wish.

Lets take a closer look at that URI:


Notice:

  • We've mapped an HTTP GET call to the url "/design/patterns/creational". Talk this out. Map a HTTP GET to the /design/patterns/creational resource and give it to me in json.
  • @httpMethod GET is the annotation to map an http method a function
  • api.cfm is the required cfm template that must exist for CF to parse the uri. This can be named whatever you want. index.cfm, rest.cfm, I just arbitrarily named it api.cfm. Again, as with any request that must go ColdFusion, you must go through a cfm page. In Quicksilver, however, that cfm page does not need to exist. Just the fact that its in the URL is enough, we'll take care of the rest. In our example, api.cfm is not a real file.
  • After api.cfm comes the path we set in our @url annotation.
  • Automatic Serialization - Quicksilver will automatically serialize arrays, structs and queries to json for you and since our return type is an array, automatic serialization is kicks in.
  • By default the return of this call also returns an HTTP status code of 200. You have full control over the status codes as well.
Easy right? Imagine this uri being called via ajax call from jQuery, ExtJS or whatever ajax feature you use. You'll get a json representation back.

Lastly, you've heard use say again and again that the Quicksilver framework does not get in your way and keeps your codebase HIGHLY testable. We're not just saying this to sound cool, we'll prove it. Lets re-run our unit test even after we  activated REST.



Look at that :) Test still passed. There's your proof. Quicksilver doesn't inject itself into your code rather it hangs out outside of it. It allows you to implement code and test without the framework in your way and we mean it. How? Via annotations baby! Read more about in the Quicksilver primer post if your confused.


side note: Just FYI - Quicksilver also supports custom representations prepended with whatever extension you want - .extjs? .pdf? .myCoolExtension?. Also allows you to have FULL control on HTTP status codes that are returned as well as the ability to send variables via the URL, http raw post, form post etc.  No problem. We'll get to that in future blog posts, promise. Or check out Brian's Quicksilver blog. Link at the end of the article.


So to wrap up, I hope you now see how Quicksilver is as unobtrusive as possible. We REST'd our application with no added components, no messy soap web services, no duplicate code all while remaining organized and  highly testable. No framework artifacts riddling your awesome code. How about that? A framework that actually cares about risk management.

-Micky

Resources
Quicksilver Blog - entries by the one and only Brian Carr. Check it out!

Tuesday, December 8, 2009

Quicksilver Framework - A Primer

Let's chat about some Quicksilver! Quicksilver was created by a good friend of mine, Brian Carr, who has brought us the first RESTful framework for CF called Powernap. For reasons unknown to me he has given me the honor of working side by side with him on  Quicksilver - a framework that  allows programmers to quickly create MVC applications with some powerful and flexible features.


When we say powerful features, we mean it. We all know that  MVC is powerful and flexible because its given.... No need to stress that. The fact that "MVC" is in the Quicksilver USP is enough. When we use the words powerful and flexible we are truly talking about the features as well. QS offers so much more than just MVC. So... much... more.


At a high level, here are the 4(+1) core tenets that we stuck to when developing QS:

  1. Provide MVC 
  2. Native Aspect Oriented Programming(AOP) capabilities
  3. Provide Automatic Dependency Injection
  4. Provide fully functioning REST support
  5. Provide 1-4 easily and transparently as possible meaning there should be no framework artifacts in your actual implementation code getting in your way resulting in an app that becomes extremely dependent on its framework. If we achieved this we can guarantee that your application remains HIGHLY testable which means better and more focused tests, which leads to non-fragile software, which leads to happy customers and ultimately you not having to be a nervous wreck every time a code migration is ordered.
So how did we achieve this? By using Annotations. We took a page from Java/C++ and refer to them as annotations but other popular programming languages have the same feature but named differently e.g. C# calls them Attributes. Although there are many different flavors of annotations from language to language, at the end of the day annotations will provide metadata for your class files, its members and source code. With the release of CF9, you can append this metadata by way of using the cf comments with two asterisks like so:
Notice how the property is annotated via a code comment that this factory property should have a type of "path.to.some.factory". What's so cool about this? It's because an annotation is not part of implementation code - code that goes inside an actual method to be run or as a class member. Anything inside this annotation is available to the developer to introspect at runtime but actual implementation code knows nothing about it. This gives developers the ability at "compile" time to introspect source and perhaps churn out automated documentation, run debug level tests when "compilation" is running in debug mode, or in our case build a framework that gives you some really powerful features like the ones I explained above.


My intent on this entry was not to touch on every single one of those points but lets start with one - Automatic Dependency Injection. If you look at the example above we are simply telling the object that it should have a property called "factory" that has a type of "some.path.to.factory". No dependency injection going on here son, zero. That is unless you've installed Quicksilver and have either Lightwire or Coldspring installed in root. QS will by default look to see if you have Lightwire installed if not it looks for Coldspring. We decided to go with Lightwire first since it manages transient objects better than Coldspring. Ok back to the code - you've installed QS and Lightwire and now when you create your object, QS will automatically inject those dependencies for you. No XML, no bean configuration, nothing. Just the simple fact that you've annotated your property with the type is enough, QS takes care of the rest. So when you ask for an object that has property annotations attached with either the @type annotation or even inline property declaration like - property name="factory" type="some.type", you will have a proper object and its correct dependencies.


But what about for our interface based programmers that love properties that are of an interface type? Properties that doesn't have an actual concrete implementation defined as a type? Good fricking question! Here's how QS supports that with an addition annotation.










Simple type your property to the interface then use the @implementation annotation to give the actual concrete type. Your property still stays polymorphic and the world is good to you again.


So now you see the power of QS by way of annotations. QS exposes all of its features through annotations. We grew tired of having framework artifacts littered throughout code. Controllers that needed to instantiate this and extend that. XML configs spanning hundreds and hundreds of lines. With QS you get MVC without that nonsense and so much more on top of that. And we've tried our best to make sure that the "so much more" is NOT a pain for you to implement when time comes to use them like AOP or REST. 


Brian and I are putting QS to the test. You've heard me talk about the new platform that we're writing from scratch. This project uses Quicksilver so know that its being actively developed. I spoke with Brian and we've got an updated QS release coming up soon so please friends do check it out, find some bugs and put it through the ringer. Brian and I are always open to questions and feedback so definitely reach out.


With that primer out of the way, we'll dive head first into the AOP or REST capabilities of Quicksilver. What you think?


Later friends.
-Mick