Tuesday, December 18, 2012

A Simple Java Http Client

I recently needed to make an HTTP call from my AppEngine application, which uses the standard java.net classes for its urlFetch service.  Doing something as simple as an HTTP request in Java is a lot more complicated than one would hope.  Since I didn't find the process intuitive at all, I wrote this little Java HTTP client that works the way I think of HTTP.

Along the way I got to experiment with generics, which allowed me to make chained method calls so I can effectively make the whole HTTP request and get the response in one line of code (sort of).  The whole client consists of three classes and uses only core java classes, so no external libraries are needed (and it can run on AppEngine).

Message.java

This class forms the basis for the Request and Response classes.  Message is an abstract class, and contains only those things that are common to both Requests and Responses, e.g. headers and a body.

Request.java

This class does most of the heavy lifting.  It contains fields and methods for dealing with the URL and Query String, as well as several private methods that handle the messy "under the covers" networking stuff.

Response.java

This class has a few things that are only relevant to a Response, e.g. the response code and message.

How to use it:


Here's an example of a simple GET request:

// Issues a GET to Google
Response httpResponse = new Request("http://example.com")
        .getResource();

String responseBody = httpResponse.getBody();

Here's a GET request with a header and a query parameter specified:

Response httpResponse = new Request("http://example.com")
        .addHeader("x-my-header", "foobar")
        .addQueryParameter("foo", "bar")
        .getResource();

String responseBody = httpResponse.getBody();

Here's a more complicated example of a POST request with query parameters and custom headers:

// Posts a simple JSON object to the server
Response httpResponse = new Request("http://example.com")
        .addHeader("x-my-header", "foobar")
        .addQueryParameter("foo", "bar")
        .setBody("{foo: 'bar'}")
        .postResource();

String responseBody = httpResponse.getBody();


I put the whole thing on GitHub if anyone wants to try it out.  Plus, a Tip of the Hat goes to Ben Fagin for a great blog post explaining how to use generics and inheritance to create fluent APIs.

Wednesday, December 12, 2012

Polymorphism in Objectify

I'm currently learning how to use Objectify with Google AppEngine (GAE).  I was tripped-up while trying to use the polymorphic capabilities of Objectify.  With the patient help of Jeff on the objectify-appengine group, I realized that I was confusing Objectify's polymorphic object hierarchy with my code's inheritance tree.

I put together a demo to illustrate the difference.  Consider an object hierarchy where Vehicle is extended by Car and Motorcycle:

Vehicle.java:

@Entity
public class Vehicle extends Foundation {
    @Id
    private String licensePlate;

    @Index
    int numWheels;

    @Index
    int numCylinders;

    public String getLicensePlate() {
        return licensePlate;
    }

    public void setLicensePlate(String licensePlate) {
        this.licensePlate = licensePlate;
    }
}


Here are the meanings of the annotations on the Vehicle class:

  • @Entity - Makes the Vehicle class the root of a Objectify polymorphic hierarchy.  An application could have many roots that are unrelated to each other.  e.g. Vehicle, Fruit, Planet, etc.
  • @Id - This tells Objectify that the licensePlate field will be used as the unique identifier for this Vehicle; it will make up the Id part of the underlying datastore Key.
  • @Index - This will cause the numWheels and numCylinders fields to be indexed in the datastore.  This is required if you want to perform a query for Vehicles with a certain number of wheels or cylinders.

Car.java:


@EntitySubclass
public class Car extends Vehicle {

    @Index
    private int numDoors;

    public Car() {
        numWheels = 4;
        numCylinders = 4;
        numDoors = 4;
    }
}


Motorcycle.java:


@EntitySubclass
public class Motorcycle extends Vehicle {

    public Motorcycle() {
        numWheels = 2;
        numCylinders = 4;
    }
}


Here are the meanings of the annotations on the Car and Motorcycle classes:

  • @EntitySubclass - Makes the Car and Motorcycle classes descendants of Vehicle.
  • @Index - This will cause the numDoors field to be indexed in the datastore.  This will allow you to query for Vehicles with a certain number of doors.

You may have noticed that the Vehicle class extends Foundation.  Here's a look at...

Foundation.java:


public class Foundation {
    /**
     * @return A JSON representation of this entity.
     */
    public String toJSON() {
        return new JSONObject(this).toString();
    }
}

This is where I got tripped-up when I started coding with Objectify.  Foundation is the root of my inheritance tree (excluding Object, of course), but it is NOT the root of my Objectify hierarchy.  I originally had the @Entity annotation on Foundation, which does not make sense because Foundation will be extended by all manner of unrelated classes.  (It simply holds a method so that any entity can represent itself as a JSON string).  The @Entity annotation belongs on the root of each of your polymorphic hierarchies; Vehicle in this case.


Monday, December 10, 2012

Wearing the Golden Handcuffs

I've been working at the same job for the same company for over a decade. In my line of work as a Programmer/Analyst, that's an eternity.  I work for a great boss, at a great company, making good money, doing work that is more-or-less fulfilling, but somehow it is all just getting a little "old".  Ever since Carl showed up as a stockholder, things have been changing around the company. We're no longer obsessed with providing better services than our competitors, but instead we're worried about aligning our expense structure to be the same as everyone else in our industry.

I know I should be grateful to have reliable employment these days, but I can feel my skills becoming less and less relevant every day, and I long for the days when I could experiment and try new technologies without having to fight against deeply entrenched tools and philosophies.  I feel it is my duty to myself to keep my skills current and relevant to what's happening in the marketplace today, should I suddenly find myself out in the cold.

With that in mind, I've decided to start exploring the new technologies that have developed over the last decade, that I've largely been shielded from using. I'm going to use this blog to share some of the stuff I learn, at least for those things that might be interesting to others. Stay tuned if you want to hear more about a newbie's perspective on things like Amazon Web Services, Google's AppEngine, RESTful APIs, Sencha, Popcorn.js, and anything Smart TV-related. (more on that later…)