Tuesday, April 5, 2011

What's missing from our REST Services?

While reading the excellent book RESTful Web Services I discovered something. A technique used on the web since its beginning. Twitter and Facebook seem to use it. Yet it was absent in the REST Services I had been developing and if I had to guess most REST developers aren't including it either. What is so valuable the Internet would be useless without it? The answer is hypermedia.

Hypermedia is the technical term used to describe how web pages (resources) are linked or connected. The author of RESTful Web Services calls it connectedness: how the server guides the client from one application state to another by providing links. A good example of a well-connected application is Wikipedia. It's very powerful when you could pick a random page and click through every entry on Wikipedia without ever editing your browsers URL. Performing a search on Google is another great example, as it wouldn't be very useful if the search result didn't include any links. Without these links, the client must know and create predefined rules to build every URL it wants to visit.

So what do links on a website have to do with REST Services? REST was built on the foundation of the web and just because your not returning HTML doesn't mean you shouldn't create relationships between your resources. In fact, it's amazing how powerful embedding links in your responses can be. For instance, it prevents tight coupling between your clients and services as the clients don't have to construct or even know the exact URLs because the services are providing them.

Let's use Twitter as an example. Assume the following is the URL to get the 20 most recent tweets for my account:

http://api.twitter.com/1/statuses/user_timeline.json?screen_name=jlorenzen

And here is a shortened fictitious response:

[
    {
        "text": "Finished watching Battlestar Galatica"
        "id": "55947977415667712"
        "url": "http://api.twitter.com/1/statuses/show/55947977415667712.json"
    },
    {
        "text": "Started watching Battlestar Galatica"
        "id": "45947977415667712"
        "url": "http://api.twitter.com/1/statuses/show/45947977415667712.json"
    }
]

Notice each tweet includes a direct URL. Now clients can use that URL value verses constructing it, and if it changes in the future, clients don't have to make any changes.

Example using Jersey
So what is the best way to include links in your REST Services? Since I use Jersey on a daily basis, I'll go ahead and show an example of how to embed links in your responses using Jersey. Most likely, any REST framework is going to provide the same kind of features.

Using the twitter example above, the User Status Service with links may look something like this (using groovy):

import javax.ws.rs.GET
import javax.ws.rs.Path
import javax.ws.rs.Produces
import javax.ws.rs.QueryParam
import javax.ws.rs.core.Context
import javax.ws.rs.core.UriInfo

import com.test.UserStatuses

@Path("/statuses")
class StatusesResource {
 
    @Context 
    UriInfo uriInfo

    @GET
    @Path("/user_timeline")
    @Produces(["application/json", "application/xml"])
    def UserStatuses getUserTimeline(@QueryParam("screen_name")String screen_name) {
        def statuses = getStatuses(screen_name)
        
        statuses.each {
            it.url = "${uriInfo.baseUri}statuses/show/$it.id"
        }
        
        return new UserStatuses(statuses: statuses)
    }
}

In this simple example, Jersey injects the UriInfo object which we use to get the baseUri of the request. It's really that simple.


Potential Issues
Well for some it may not be that simple. For example, we discovered an issue when using a reverse proxy (apache httpd). In our production environments, we typically setup apache on port 80 to proxy a localhost JBoss on port 8080. Unfortunately, in this setup the UriInfo.getBaseUri() returns localhost:8080 and not the actual original URL the client used; which is obviously not good. Now if you don't use a reverse proxy then no worries. However, if you do or might potentially in the future, a easy solution seems to be to set the Apache Proxy module option ProxyPreserveHost to On. Setting this to On and restarting Apache seems to fix the issue.

JSONView Firefox Plugin
Once you've started embedding URLs in your REST responses, you might find it useful to install the JSONView firefox plugin. It's got some really slick features like formatting the JSON and creating clickable links for URLs.

Friday, October 1, 2010

How to Change Extjs PieChart Colors

When using Sencha's, or extjs, charting capability, most likely your going to want to change the default color scheme. I was faced with this issue today and it's not documented as well as you'd expect. I had to piece together a few articles and I'm still not 100% it's the right way as it's using an undocumented config option. But I wanted to document how I did get it to work to same others some time.

Sencha is very well documented and their examples are great. Here is the Pie Chart example we are going to be updating (using version 3.2.1). For those that don't know, extjs charts are based off of Yahoo's YUI charts which is also requires Flash. Not only is it pretty simple to create charts with extjs, but we already are using extjs so we decided to prototype some charts using it.

Here is the code that produces a simple basic PieChart:

new Ext.Panel({
    width: 400,
    height: 400,
    title: 'Pie Chart with Legend - Favorite Season',
    renderTo: 'container',
    items: {
        store: store,
        xtype: 'piechart',
        dataField: 'total',
        categoryField: 'season',
        extraStyle:
        {
            legend:
            {
                display: 'bottom',
                padding: 5,
                font:
                {
                    family: 'Tahoma',
                    size: 13
                }
            }
        }
    }
}); 

This produces the following PieChart.

To change the default colors provide a series config option:
new Ext.Panel({
    width: 400,
    height: 400,
    title: 'Pie Chart with Legend - Favorite Season',
    renderTo: 'container',
    items: {
        store: store,
        xtype: 'piechart',
        dataField: 'total',
        categoryField: 'season',
        series: [{
            style: {
                colors: ["#ff2400", "#94660e", "#00b8bf", "#edff9f"]
            }
        }],
        extraStyle:
        {
            legend:
            {
                display: 'bottom',
                padding: 5,
                font:
                {
                    family: 'Tahoma',
                    size: 13
                }
            }
        }
    }
});

The chart it produces may not look the most appealing but at least we figured out how to change the colors.
Pie Chart with New Colors


Again, I'm not certain this is the best way to accomplish this as the series config option isn't documented in 3.2.1. But by piecing together this PieChart question and this article, I was able to figure it out.

Thursday, August 19, 2010

Missing Office Equipment Prank

Here is Part 2 of my series where I reminisce about the good times I had at Williams. As I stated previously, I came across these printed off emails in our attic while moving to our new home. I'm so glad I printed them off. #goodtimes

Anyway, this was a prank Keith Stanek, Josh Guthman (Guthy), and myself pulled on Michael Brotherman (Are you Miking Me?). Before showing you the email though I need to set the stage. The year was 2003, and our company had just gone through 3 rounds of layoffs. Morale was pretty low. We worked on the 32nd floor of the 52 story BOK building in downtown Tulsa, Oklahoma. During fire drills we had to take the stairs down a floor. During one of the fire drills we noticed the entire 31st floor was void of humans, but a lot of very nice unused office furniture and white boards were still present. We joked around about repurposing some of the nicer equipment, but nothing ever come of it. Until one morning, we noticed Mike had a new chair. A very nice new chair. We gave him junk about it all day, but decided a prank would be better. So we had Josh Guthman (Guthy) write us up a believable email that Keith and I would spoof using the Facilities email address. Here it is:

From: Facilities Services-Tulsa
Sent: Thursday, March 13, 2003 7:39AM
Subject: Missing Office Equipment

During a recent audit for unused office equipment we discovered black reclining office chairs were missing from several of the floors in the BOK tower. Upon further investigation we discovered those chairs had been procured by current employees looking to upgrade from their existing chairs. While facilities appreciates your desire to utilize existing assets instead of requisitioning new ones, please remember that Williams is undergoing a cost savings campaign at this time and that all unused equipment needs to remain on its respective floor for proper accounting and redistribution either to the lessee or to an employee in need. If we have not already reacquired your chair, please return it to the floor from which it came by the end of business Friday, March 14.

Mike smelled it out, but noone ever confessed, and I'm pretty sure deep down, even though his gut was telling him it was a prank, he still didn't want to take the chance in the possibility that it might have been true. The best part about it was the morning we sent the email, Mike and I had a group breakfast meeting with one of the Senior Executives. As we were going down the elevator, he mentioned to me that he was going to bring it up during the meeting, and with a complete straight face I called his bluff and told him that I think he should, knowing that he wouldn't anyway; and if he did it would only make the prank that much better.

Mike returned the chair.