Tuesday, November 24, 2009

My thoughts on Google's Chrome OS

Unless you've been living under a rock, you have heard that last week Google demonstrated their Chrome OS for the first time in public. They also open-sourced what they have so far as the Chromium OS project. You can watch an overview video here:

I followed the event, watched the YouTube videos and even played with a copy of Chromium OS via gdgt.

So here are my thoughts on my limited experience so far. It seems like a perfect fit for the netbook market. "Living in the cloud" seems like a great idea for the ability to access your data anywhere. A verified boot system will be a godsend to anyone who has ever had reinstall an OS because it just got 'crufty'.

But I don't understand why they have, so far, omitted the concept of a desktop. One of the coolest features of Chrome is its ability to turn a web app into a 'desktop' app, which prompted me to to find Fluid for the Mac. Why force new users of Chrome OS to live in a browser when they could have still kept the concepts of a desktop with 'desktop' applications? There is also a nearly direct analogy in Chrome OS between its tabs and the Windows task bar or Mac Dock. So why make it feel so different instead of trying to fit into the conventions every other GUI-based OS already established?

I know it is fun to "rock the boat" and "shake the tree", but I'm just not finding the benefits to tying so closely to existing browser paradigms instead of reusing some of the desktop conventions for this new 'web' OS.

Monday, November 16, 2009

Maven and Legacy Projects

Recently I've been helping a colleague introduce a dependency on a legacy project that hasn't been "Maven-ized". Often the "easy way" to add a legacy dependency is to throw the JAR into our Nexus repository and be done with it. But this legacy project was a little trickier and is my new poster child for why taking the easy way can lead to headaches and frustration.

Your legacy project might have compile-time dependencies you need.
Maybe your legacy project implements an external API, or maybe it uses a library and exposes that usage in its API. "So what", you say? "I'll find it at compile-time for my project and I'll add the dependency." Well, now every project that wants to use your legacy project is going to go through the same discovery and embed the dependency in their POM. The right way is to define this dependency in the pom.xml for your legacy project so all dependent projects retrieve it transitively.

Your legacy project might have run-time dependencies you need.
Similar to the last example, your legacy project might use a library but not expose it's use directly. You won't discover the missing dependency until you try and run your project. Here's where the power of the 'runtime' scope of a transitive dependency becomes obvious.

Your legacy project might include library classes within its JAR.
Now here's a real yuck factor when it comes to dealing with other people's code. Our example legacy project bundled a small subset of its dependencies right in its JAR. It wasn't until after we threw it into Nexus that we discovered this rather severe violation of Maven standards. The best solution, get access to the project's source, mavenize the project properly and release a 'pure' artifact. If you don't have access to the legacy project's source you'll need to strip the extra classes from the artifact and construct a pom that includes the right dependency.

So here's a really quick summary of why not to half-ass adding legacy projects into your Maven infrastructure:
  • Any transitive dependencies will be missing.
  • With legacy jars that embed the classes they depend on you risk class file collisions

Tuesday, November 10, 2009

Medicine is so Young

I think its undeniable that one of the hottest topic of this year is health care. While I've been casually following the political discourse, its far from my inspiration for today's post. My one year old son, Wally, had a reaction to penicillin this week and I question why current medicine is still so reactive rather than proactive. Since allergies are something that can change and fluctuate, that led me to also wonder why we don't have more frequent testing too.

Standardized testing
I'm looking forward to the day when there is a standard battery of tests for allergies and conditions. It's beginning with the prenatal screenings available during both of my wife's pregnancies, but why, for instance, is there no standard allergy testing post-birth? From the perspective of a patient, current medicine waits for a reaction to an allergen which seems so dangerous to me.

Continuous diagnostics

When can I get my little implant that continuously monitors my blood-work and vitals? I've been dealing with the medical 'miscellaneous bucket' that is IBS for 6 years now and don't feel like I'll ever get an answer about what is really afflicting me. I see my doctor once a year, and she doesn't really seem to have an answer. I know, I know, demand answers, fight for myself, blah blah, that's not my point. It's currently not 'bad enough' to force me to demand anything yet. I bring up my current state during my annual checkup, and that's about all I feel I'm empowered to do right now. I strongly believe if there were a way to easily and continuously monitor medical data points (blood, hormone, etc) within my body and let me correlate that with the ebb and flow of symptoms there would be a much higher chance of being able to find the problem.

Online records

I've been 'using' Google Health since it was released last year. But my doctor's office has no tie to my account so I'm forced to update it by hand. Not to mention all my historical data is no where to be found. For the providers that Google Health does currently support linking, I have a 50% success rate getting them to work. I was able to link my CVS prescriptions but failed to link my Quest test results. When I followed Quest's instructions, the receptionist at the testing facility looked at me like I had three heads when I asked to get my results online. She had no idea what I was talking about.

Wednesday, November 04, 2009

What REST is NOT, Updated

In a surprising update to my post earlier this week about what REST is NOT, I just spoke with Rooly Eliezerov, the President and co-founder of Gigya. We had a nice conversation about the goals of Gigya, primarily that they want to aggregate these other social web services and their design philosophy is to mimic Facebook and Twitter's API. I expressed that using GET to change a resource isn't a REST principle either company's API breaks. He was surprised to hear it and said he'd follow-up with his team to validate that and get back to me.

Whatever the outcome, I really appreciate that a company with their goals and reach is interested in what little ol' me has to say. It speaks volumes to their passion and customer support.

Tuesday, November 03, 2009

Problems of the MPAA's Digital Copy system

When I got 'Wanted' on DVD as a gift, it was the first movie on disc (DVD or Blu-ray) that included a Digital Copy. Since my home media setup is all iTunes/Apple-based I easily popped in the extra disc, entered the included key and added the "Wanted" to my media collection in less than 5 minutes. It was beautiful and enlightening. I'm on the side of the fence that copying a movie onto a private home media network is an ethical, though not currently legal, fair use of copyrighted works.

Usually ripping a DVD for me is a 'set it and forget' operation using Handbrake that takes several elapsed hours but little interaction. But with the latest copy-protection features of DVDs it can be a hit-or-miss prospect which has caused me to add a few corrupted movies to my collection. And if I want to take the time to attempt to circumvent the copy-protection using Mac the Ripper or RipIt, it's again hit-or-miss and makes the process that much more labor-intensive, at a time in my life where I have little desire or time desire to dedicate to building my media collection.

Seeing how quick, easy and reliable using the Digital Copy process was and how it resulted in a copy that can play on my mobile device (iPhone), HTPC (Mac mini) and set-top box (AppleTV) was exactly what I've wanted! And now having a Blu-ray player but no way to import those movies into my media collection, I thought Blu-ray + Digital Copy was the killer combination. But with my third purchase of a feature that included a Digital Copy, the honeymoon is over.

Here's what I think is missing from the current Digital Copy system:
  1. DRM-free
  2. HD
  3. Quality consistency
  4. Ownership transfer/lending
At first, the DRM didn't bother me. Then I started to worry about what happens when I have a catastrophic data failure of some kind? Sure I back up my files including my ripped videos, and I've even started making a second off-site backup but will I have to jump through hoops to play them again? How simple is the process of re-adding them to my collection if I get a new computer?

Also, I found expiration dates for all three keys I currently have, what if I have to reauthorize them after the expiration date? In fact my third purchase was made after the listed expiration date, but luckily I didn't have a problem activating the Digital Copy, which was a bit of a relief. In general I'm worried about the ramifications of an expiration date on the activation key.

High Definition
Now if I buy a DVD with a Digital Copy, I'm not greedy and I don't expect an HD Digital Copy. But for the one Blu-ray I've purchased with a Digital Copy I'd expect at least a 720p HD copy as if I had purchased it in HD the iTunes Store.

Quality consistency
Another surprising thing for one of the movies I purchased, "The Nightmare Before Christmas", I noticed a drastic difference in the aspect ratio of the Digital Copy compared to the DVD video. The DVD was clearly full-frame 16:9 but the Digital Copy was somewhere between 4:3 and 16:9. My guess is its the original theatrical aspect ratio and the DVD version was cropped to 16:9.

Ownership transfers and lending
What happens when I want to lend, give or sell the DVD to a friend? I think what Barnes&Noble is doing with the Nook is the most realistic option, allow 14-day lending of digital rights to a friend. If they can make it work, why can Apple and Microsoft?

Monday, November 02, 2009

What REST is NOT

Update: I spoke with the president of Gigya.

Having only familiarized myself with REST a few months ago, I still struggle to explain to colleagues what REST is. My best one sentence summary so far is that it's "using HTTP as it was designed". Not a perfect or even complete summary, but I think it covers the highlights.

This week I've been reviewing Gigya's REST APIs for an upcoming project at work. And I've found it to be a shining example of designing an API incorrectly and calling it RESTful. It solidified a couple of REST anti-patterns for me and I wanted to capture them:
  1. REST is not RPC, though RPC can be done RESTfully.
  2. GET is not for state changes. If you're operation has side effects, don't use GET.
  3. The response body is not the only way to send the client information. Don't duplicate information in the HTTP headers in the response body.
  4. Authentication is not part of your resource. Don't create a query parameter to do authentication, use the HTTP header that already exists for the purpose.
REST is not RPC
Many developers coming from a SOAP background think RPC calls can be ported to 'REST' and then call it a day. They are missing a big mental shift in the way to think of web services when designing using REST principles. Instead of thinking of services as functions that can be called, change your thinking to performing operations on objects, formally known as 'resources' in REST parlance. The operations you can perform on your resource are the existing HTTP methods, GET, POST, PUT, DELETE, OPTIONS and HEAD. So instead of exposing a 'setStatus' function via a web service, instead expose a 'status' resource that can be POSTed or PUT to change it, call GET to retrieve the current status, or DELETE it to clear the status. REST is not functional RPC, its a paradigm shift to treating web services in an object-oriented way.

GET is not for state changes
The most important REST principle that Gigya's APIs violate is using GET calls to affect the state of a resource. Short of recording access, like last viewed by/on, GET calls should never affect the state of the resource it represents. If you need to change a resource, there are three other HTTP methods for that purpose, namely POST, PUT and DELETE. The use cases for DELETE are pretty self-apparent, but I've got to admit to being confused of when I should choose POST vs. PUT. John Calcote clarified the answer nicely of when to choose POST over PUT.

The response body is not the only way to send the client information
HTTP headers, for both requests and responses, can be an invaluable way to simplify your API. They can contain rich information about the success (200 OK, 201 Created, 204 No Content) and failure (404 Not Found, 401 Not Authorized, 503 Service Unavailable) of a request. Gigya for example includes the HTTP status code in their XML response body. It seems like a waste of bandwidth to me, when the status code is already included in the response headers. To their credit their documentation seems to imply the codes are more detailed than available in the HTTP spec (500-001, etc) but their examples conflict with that and only show the XML return simple HTTP codes with HTTP reason messages. Even if they provide more detailed information, it should not duplicate what already exists in the request. Trust that your API users can understand and use the headers. Its much easier to only check a status code instead of parsing an XML response.

Authentication is not part of your resource
This antipattern is directly related to my last point of using HTTP headers properly but its important enough to warrant its own bullet. This violation is a version of "don't reinvent the wheel". Gigya has for some strange reason taken OAuth and permuted its use rather than sticking to the spec. They even have API users sign their requests using OAuth libraries but then fail to carry that through into the API usage. The signature a part of the GET query string rather than use the already established HTTP header that the OAuth spec has defined for carrying that data point.

REST is a very amorphous set of principles but that doesn't mean there are no concrete guidelines. Patterns are emerging as well as anti-patterns and Gigya has examples of both. I don't mean to pick on Gigya but they just happened to be freshest examples in my mind this week. The big points I'd like you to take away from this are, don't reinvent the wheel, use the existing HTTP methods properly, don't forget that HTTP headers exist and design your APIs by thinking of them as objects rather than functions.

Tuesday, September 22, 2009

Parenthood | Sweetness or Manipulation?

So Sunday night (Sept 20), I realized my three year old daughter Penelope is either extremely manipulative or extremely sweet. We were doing bedtime, reading a book and bedtime was over. She was supposed to lay down and go to sleep. I went to get a drink before heading up for the night and as I walk past her room again I see her standing at the foot of her bed in the dark. She calls out "Daddy, daddy! Poopies are coming!". Now I've learned this is a common stall tactic with her.

So I said, "No! Poopies are not coming. Go to sleep". But she insisted and so I threatened, that if she didn't really have to go to the bathroom I was going to take away her favorite bunny, which has become her security blanket.

So she agrees and gets out of bed and goes to the bathroom. So she's sitting there and nothing's coming out. And I'm like "Penelope, I told you what would happen right?" So I give her some more time and then come back.

I open the door and say "Time's up, any poopies?". She says "No.", and hangs her head in shame. She then follows it with one of the most heartwrenching statements yet, "It's okay Daddy, I not cry. I big girl. You can take bunny."

So I think oh no, I'm a terrible father, I can't take her bunny... So I said, "Just because of that, you get to keep your bunny." She gives me a huge grin and says "Oh Daddy! Thank you Daddy! I love you Daddy!" And she gives me a big hug and I pick her up, and she's patting my back and says "Good Daddy! Good Daddy!" like I bought her a new car.

Kids are awesome.

Tuesday, July 07, 2009

1Password is an essential app

Today I posted a Facebook status that I've come around and consider 1Password a must-have app for every Mac user. A friend commented that he didn't get it, much for the same reasons I held out for a long time. So here's how I explained my new love:

Yeah I didn't 'get' the benefit for a long time. But recently I've been frustrated with the countless number of passwords I've got and how every site has a different policy that forces me to rethink my password scheme. I started to feel like my scheme was becoming too simple just so I can meet the lowest common denominator. Also, I recently find myself forgetting the less frequently used password and needing to reset them. I needed a solution.

The killer features for me:
  1. Killer browser integration, replaces Firefox and Safari password managers
  2. Password generator, now I don't need to fear that my online passwords are crackable. Again #1 makes #2 awesomely simple.
  3. Slick iPhone integration. I can take and update my passwords anywhere. Better Mobile Safari integration would be nice, but that's due to Apple's limitations.
  4. Master password: I know, I know, single point of failure right? I'm now of the opinion its much more likely a hacker will get access to one of my passwords online and figure out my simple scheme rather than them gaining access to my computer and cracking my rather complex master password. For me its more peace of mind and the simplicity of not having to memorize all my different passwords.
  5. Easy syncing via Dropbox. I want autofill not just cross-browser but cross-computer too. http://webworkerdaily.com/2008/09/29/1password-dropbox-sync/
Oh and I remembered to search for coupon codes before buying it. I used "iSlayer" which gave me 20% off.

Sunday, April 19, 2009

HandleCheck: My Google App Engine and Open Source Project

So I signed up for a Google App Engine account a while ago, almost right after it's Python version was released last year. Of course, life prevented me from taking the time to learn Python, and so the learning curve prevented me from building or deploying anything.

Fast-forward to two weeks ago when Google released the Java API for the Google App Engine (GAE from here on out). Being a full-time Java programmer for the past 10 years, now we're running on all cylinders! I applied for a Java account on the day it was released and my Java GAE account was approved within 24 hours, but it took a few days for me to make some time to start writing some code. After about 8 hours of development I had my first working prototype of a web application running on the GAE.

My first GAE webapp is a service that connects to a set of social web sites that provide user names and profile pages for their users to see if a username you are interested is still available across those sites. My app is a called Handlecheck (handle in the sense of "username") and is live now at http://handlecheck.jaxzin.com.

This is also the first project I've open-sourced. I did a little reading on how to pick from the various open source licenses and settled on the GPLv3. I'm maintaining the source on Google Code.