Adding Static Content To Spring Boot MVC

As I learn new frameworks, I often get a good idea stuck in my head that I really want to implement. Often, the idea is overly ambitious for my knowledge of the tool, but sometimes it hits the sweet spot between “That should be pretty easy to implement” and “I really don’t want to dig into the documentation to figure this out”.

Using a tool that is rather young, like Spring Boot, makes me dread the learning process even more as they often don’t have the documentation I need in place, so instead I need to dig through source code and examples that look related.

My plan was to add static content to a Spring Boot web site. I’ve seen the dynamic content via Spring

@Controller

s, but I still need to add images and CSS if I want a decent site.

So, my journey began at Spring Boot’s GitHub repo, which has a large number of undocumented examples. My answer, of course, lay beneath the folders of the well named spring-boot-sample-web-static example, and like all other Spring Boot defaults, it was an obvious solution.

Add the static files to

src/main/webapp

. Where else would you put it?

My own example is now on GitHub which combines the Ember.js template project to the Spring Boot REST Template project.

The last step we need to create a fully functional application is to modify the Ember.js template to pull data from the REST services.

Creating Test Services with Spring Boot

Boots on Vacation

Boots on Vacation by wonderferret

One of the coolest new technologies from the Spring Foundation has to be the new Spring Boot project. Spring Boot takes all the common template / bootstrap / setup code that everyone is doing already and just does it for you.

It also covers all the main Spring technologies: Spring MVC, Spring Batch, Spring Security, etc. Need a database? Just add the schema. Need a service? Just add a request mapping. Spring Boot will interpret your setup and start a server if needed.

GitHub already has the basics for creating simple examples. For example, from the Spring Blog (once you have the Spring Boot command line installed) the following groovy code will run a web site:

@Controller
class ThisWillActuallyRun {
    @RequestMapping("/")
    @ResponseBody
    String home() {
        return "Hello World!"
    }
}

Amazingly simple to use.

It gets a little more complicated when you need an advanced site. Specifically, what do we need in order to create a database driven REST data service? All of the code for this example is in my GitHhub repo.

Build file

Something that I always appreciate, is a gradle plugin, and Spring Boot comes through. The following build.gradle loads in Spring Boot, a few more dependencies to support Groovy, an in memory database and JSON parsing for the service, then adds a run command to make life easier.

buildscript {
    repositories {
        mavenCentral()
        maven {
            url "http://repo.springsource.org/milestone"
        }
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:0.5.0.M3")
    }
}

repositories {
    mavenCentral()
    maven {
        url "http://repo.springsource.org/milestone"
    }
}

apply plugin: 'groovy'
apply plugin: 'eclipse'
apply plugin: 'spring-boot'

sourceCompatibility = 1.6
version = '1.0'

dependencies {
    compile 'org.codehaus.groovy:groovy-all:2.1.7'
    compile 'org.springframework.boot:spring-boot-starter-web:0.5.0.M3'
    compile 'org.springframework:spring-jdbc:4.0.0.M3'
    runtime 'org.codehaus.jackson:jackson-mapper-asl:1.9.12'
    runtime 'org.hsqldb:hsqldb:latest.release'
}

task run(type: JavaExec) {
    classpath configurations.runtime, sourceSets.main.output
    main = 'com.mycom.App'
}

task wrapper(type: Wrapper) {
    gradleVersion = '1.7'
}

Project Structure

You have two options to run Spring Boot projects. The first is simply use the Spring Boot command line against a class you want to execute, as with the example from the Spring blog. The second options is for more complex projects that are set up to use an IDE and custom project structure. We’ll use the latter for this example.

I’ve used the standard Groovy Jar project structure for Gradle, but any structure will do. Note that, even though we are building a web app, the project structure is for a Jar. We have no need to create the web.xml.

Main

From the build file above, the run task simply executes the main class com.mycom.App. This class will tell Spring Boot how to run our app and set up all our autowiring needs.

package com.mycom 

import org.springframework.boot.*
import org.springframework.boot.autoconfigure.*
import org.springframework.context.annotation.ComponentScan
import org.springframework.context.annotation.Configuration
import org.springframework.stereotype.*
import org.springframework.web.bind.annotation.*

@Configuration
@ComponentScan(basePackages = "com.mycom" )
@EnableAutoConfiguration
class App {
    public static void main(String[] args) throws Exception {
        def app = new SpringApplication(App.class)
        app.showBanner = false
        app.run(args)
    }
}

I’ve shown that SpringApplication actually includes a few custom properties you may be interested in. However, in most cases, the static run(Object, args) should be enough. Otherwise, note that this class configures the rest of the classes in com.mycom for Spring wiring.

App Settings

Let’s take a detour into the resources directory. Spring Boot has additional configuration steps in the application.properties file. Simply create this file, put it on your classpath, and fill in what is needed.

spring.application.name=spring-boot-service-template
server.port:9080
logging.file:logs/system.log

spring.database.schema=classpath*:schema-hsqldb.sql

Application name, server port and logging file are all completely optional and only serve as examples. The only important information in this file is the database schema. which is also in the resources directory. Spring Boot will load the database file and create the DataSource for us.

Schema

Here’s our actual data. We’ll follow the model from the Ember example:

  • We have Franchises which represent a game franchise, like Legend of Zelda
  • Within each franchise, we have a Game
  • Each game has a release date

Our schema creates the tables and sample data in one file:

CREATE TABLE franchises (
    id BIGINT NOT NULL PRIMARY KEY,
    title VARCHAR(255)
);

CREATE TABLE games (
    id BIGINT NOT NULL,
    franchise_id BIGINT NOT NULL, 
    name VARCHAR(255),
    release DATE,
    FOREIGN KEY (franchise_id) REFERENCES franchises(id)
);

INSERT INTO franchises 
    (id, title) VALUES
    (0, 'Final Fantasy'),
    (1, 'Fire Emblem'),
    (2, 'The Legend of Zelda');

INSERT INTO games
    (franchise_id, id, name, release) VALUES
    (0, 0, 'Final Fantasy Type 0', '2011-10-27'),
    (0, 1, 'Final Fantasy IV: The After Years', '2008-02-18'),
    (0, 2, 'Final Fantasy VII', '1997-09-07'),
    (1, 0, 'Fire Emblem Awakening', '2013-02-04'),
    (1, 1, 'Fire Emblem Shadow Dragon', '2009-02-16'),
    (2, 0, 'The Legend of Zelda: Skyward Sword', '2011-11-20'),
    (2, 1, 'The Legend of Zelda: Ocarina of Time', '2007-02-26'),
    (2, 2, 'The Legend of Zelda: A Link to the Past', '1991-11-21');

Logging

Just to note that logging is already configured for Logback and SLF4J. A logback.xml on the classpath will configure logging as you would expect.

Service Code

Now to the actual service code that all the above supports. Spring Boot does all the work on configuring Spring MVC for us, so all that is left for us to do is the actual business logic for the REST services.

The services themselves will simply return the data from the database based on the resource requested. So, /franchise/1 will return Fire Emblem franchise while /franchise/1/game/0 will return Fire Emblem Awakening with its release date.

For Frachises:

package com.mycom

import javax.sql.DataSource

import org.springframework.beans.factory.annotation.Autowired
import org.springframework.dao.EmptyResultDataAccessException
import org.springframework.jdbc.core.JdbcTemplate
import org.springframework.stereotype.Controller
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.ResponseBody

@Controller
class Franchise {
    private JdbcTemplate jdbcTemplate

    @Autowired
    public Franchise(DataSource dataSource) {
        this.jdbcTemplate = new JdbcTemplate(dataSource)
    }
    
    @ResponseBody
    @RequestMapping('/franchise/{id}')
    String franchiseId(@PathVariable Long id) {
        try {
            return jdbcTemplate.queryForMap('SELECT id, title FROM franchises WHERE id=?', id)
        } catch(EmptyResultDataAccessException ex) {
            return Collections.EMPTY_MAP
        }
    }
    
    @ResponseBody
    @RequestMapping('/franchise/')
    String franchises() {
        try {
            return jdbcTemplate.queryForList('SELECT id, title FROM franchises')
        } catch(EmptyResultDataAccessException ex) {
            return Collections.EMPTY_MAP
        }
    }
}

And similarly for Games:

package com.mycom

import javax.sql.DataSource

import org.springframework.beans.factory.annotation.Autowired
import org.springframework.dao.EmptyResultDataAccessException
import org.springframework.jdbc.core.JdbcTemplate
import org.springframework.stereotype.Controller
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.ResponseBody

import com.fasterxml.jackson.databind.node.NodeCursor.Object;

@Controller
class Game {
    private JdbcTemplate jdbcTemplate

    @Autowired
    public Game(DataSource dataSource) {
        this.jdbcTemplate = new JdbcTemplate(dataSource)
    }
    
    @ResponseBody
    @RequestMapping('/franchise/{franchiseId}/game/{id}')
    String gameId(@PathVariable Long franchiseId, @PathVariable Long id) {
        try {
            return jdbcTemplate.queryForMap('SELECT id, name, release FROM games WHERE franchise_id=? AND id=?', franchiseId, id)
        } catch(EmptyResultDataAccessException ex) {
            return Collections.EMPTY_MAP
        }
    }
    
    @ResponseBody
    @RequestMapping('/franchise/{franchiseId}/game')
    String games(@PathVariable Long franchiseId) {
        try {
            return jdbcTemplate.queryForList('SELECT id, name, release FROM games WHERE franchise_id=?', franchiseId)
        } catch(EmptyResultDataAccessException ex) {
            return Collections.EMPTY_MAP
        }
    }
}

Running

And that’s it. Six code files and a build file gives us a full fledged REST service running locally, ready for an app to start consuming it.

To run the sample, open a command prompt and execute gradlew run. This will download dependencies, compile the code, package it into a jar and execute the main class.

Visit http://localhost:9080/franchise/1 and other variants to see the JSON responses.

Wrap up

Not only was the above easy to learn, but it opens up a lot of possibilities for local test services. Spring Boot can also easily be deployed to Cloud Foundry, Spring’s favored cloud provider.

In the end, how is Spring Boot anything other than magic? We currently have enough trouble accepting Groovy in an enterprise environment, and Groovy is just making Java easier to work with. Spring Boot makes Spring apps easier, so it will face the same hurdles in large organizations that Groovy faces. And, just like Groovy, the best way to introduce Spring Boot may be through testing. Because, “Who cares if it’s only used for tests”. Then, once we have it in all our tests, it will naturally begin to grow until we have production Spring Boot apps.

Hopefully, by the time this project reaches 1.0, we’ll see a lot of clever new features to make our Spring developer’s lives easier.

Do Not Fear the Computer

When starting anything new, most people have a fear of doing something, anything, wrong. For me, it is one of the most difficult reactions that I need to overcome before truly understanding a technology.

My own, personal, fear manifests as getting the implementation wrong. When I start learning a new tool or language, I become obsessed over “doing it right”. With a simple implementation in hand, I’ll start searching forums or digging into the source to try and uncover the best way to accomplish my goal. This usually wastes hours of my time when the “wrong way” works just fine. In the end, I’ll still use my simple implementation as the want for breadth of knowledge starts to overcome the want for depth of knowledge.

If I continue learning the tool, I’ll look back in a month’s or year’s time and be ashamed of my foolish, ignorant, younger self. So, really, there’s no need for the wasted time.

I’ve also seen a similar issue with some non-technical folks when it comes to computers and software in general. There is an overwhelming sense that their computer is a ticking time bomb and the wrong button or click will blow the computer to pieces or crash the OS. My wife had this fear in abundance. Over time, with a bit of hand holding, she worked through this fear, and I’m glad to say she now knows that good software understands that the user makes mistakes. That’s why PARC invented the undo command.

Fear of the computer interrupts the idea-to-execution process. Alice has an idea and wants to use her software to make it manifest. If the software is so complex that she can’t find command needed to complete the task at hand, then she may give up. Fear of the computer prevents experimentation.

Proper software needs to encourage experimentation. Any action must be reversible; any command must make its effects clear; any permanent change must be preventable. Naming of actions must take priority over all other UI features. Should posts be “Submitted” or “Published”. Depending on the context, both words may be synonyms, or they could imply non-permanent or permanent actions.

Proper software needs to understand that user’s fear that they may be “doing it wrong”. Either the software needs to make it clear that the user is indeed “doing it right” or at least let the user know they may be doing it wrong.

In the end, however it is accomplished, the software must take away the user’s fear if the creators want their work to be used.

Vulnerabilies of Good Intentions

One of the saddest vulnerabilities introduced into applications are those that are created by design. These vulnerabilities are explicitly written into application requirements or have specific user stories. Often, the vulnerability takes on the form of functionality requested by one or more stakeholders.

Consider the following: Facebook privacy flaw exposes Mark Zuckerberg photos. This flaw was created with only good intentions in mind. Facebook prides itself on keeping the site clean and inoffensive. Owners of the site look for any tool that can help weed out the bad photos from the good. Considering the size of Facebook’s image library, I would want help as well.

So, someone had a great idea: we should crowdsource the effort. Some of us can manually look through photos; maybe we can create an automated scanner to tag possibly offensive pictures; but our best bet is our user base. Those who are actually offended will be empowered to report offending pics.

Enter the Reporting feature:

  • Alice sees Eve’s photo on Facebook. The photo itself may or may not follow Facebook’s guidelines, but all that really matters here is that Alice is taken aback.
  • Alice clicks the “Report” link to alert Facebook of this deeply offensive image. She’ll need to fill out some information about why it is offensive, but it’s straight forward and she submits the form.

This feature has a few benefits: Facebook staff can be put to better use reviewing possibly offensive images instead of random images; Users get to feel good about themselves that they helped clean up a site they love; repeat offenders can be duly punished to the limits of  Facebook’s Terms and Conditions.

However, where there is one offensive picture, there could be many more. An empowered user who has already reported an image has it set in her mind that image reporting is her duty. If Alice saw the rest of Eve’s photos, she could review those as well. So, we tweak the code and a new feature is born:Alice sees Eve’s photo on Facebook. The photo itself may or may not follow Facebook’s guidelines, but all that really matters here is that Alice is taken aback.

  • Alice sees Eve’s photo on Facebook. The photo itself may or may not follow Facebook’s guidelines, but all that really matters here is that Alice is taken aback.
  • Alice clicks the “Report” link to alert Facebook of this deeply offensive image. She’ll need to fill out some information about why it is offensive, but it’s straight forward and she submits the form.
  • Facebook show’s Alice the rest of Eve’s pictures in the hope that other offensive images will be reported.
  • Alice selects more offensive images and her duty is done.

This is great functionality: User feel more empowered, as though they are helping the community as partial owners of the site; Facebook staff has even less work to do; repeat offenders are identified quicker than ever before.

However, there is one flaw in the plan that was overlooked. Because any image can be flagged as inappropriate, user avatars can be flagged as well. Avatars are public as they help with identification when searching for friends. So now, we have a way to report anyone’s avatar – which is good – but the new feature will then show us the rest of the user’s library – which is bad. It is bad because we now have access to anyone’s image library, no matter what privacy setting they used, and all we need to do is report the user’s avatar.

Finally, this takes us down to the end game: Mark Zuckerberg, CEO and founder of Facebook, holding a dead chicken by the legs. Private photos posted on the internet for all to see. All from functionality and requirements requested by the business. Functionality with only good intentions, but with a security hole one can drive a truck through.

How do we stop this? Requirements and use cases need to include abuse cases as well. That is, when listing out features and how they will be used, take a moment to think of how the features can be misused as well.

As a malicious user, I want to access private user photos in order to cause harm and mischief. How can I accomplish this?

Lets set up Ember.js

Ember.js is an interesting creature. This is the first client-side MVC I’ve looked into. Apparently calling these applications “single page apps” are looked down upon, even though they are driven from a single HTML page. Single DOM applications seems more appropriate.

Based on previous experience learning new technologies, I’ve found that I am only able to understand the technology once I have a model of what’s going on behind the scenes. It was only when I realized how reflection and Java Beans could be used to implement Spring’s inversion of control that I could really start working with it.

Before this understanding occurs, everything is magic. I don’t like programming that runs on magic as magic is rather unpredictable.

With Ember.js, I struggled to follow how the examples and samples pulled everything together, but then I read the Naming Conventions document, and everything became clear.

To be honest, the Ember guides are quite good. They take a conversational approach to documentation instead of a fact based approach.

However, all the examples available so far have tried too hard to make the example “pretty” or “realistic”. That is, the examples have plenty of HTML structure to support CSS styles and the data model pulls from a related REST service with Ember Data. This detracts from the learning process. Yes, the result looks pretty, and the data is dynamic, but the example code is cluttered and involves concepts outside of Ember.js itself.

The Ugly App

So, here’s my example, an ugly Ember.js app. It does very little: When we visit the app, a list of game franchises are listed; clicking on a franchise will list games in the franchise; and clicking on a game will show us the original release date.

This is supposed to be simple and will help show off different parts of Ember such as routes and how they connect the model to the template.

Lets get the annoying stuff out the way: This example uses Ember.js 1.0 RC6. It consists of an HTML page, a javascript file representing the application, and all dependencies. You can find the code on GitHub here: https://github.com/jaylindquist/ember-template

Since we aren’t using any styles, out base HTML page is a bit bare, but we still need it:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Ember Template</title>
</head>
<body>

<!-- ember templates go here -->

<script src="js/libs/jquery-1.9.1.js"></script>
<script src="js/libs/handlebars-1.0.0-rc.4.js"></script>
<script src="js/libs/ember-1.0.0-rc.6.js"></script>
<script src="js/libs/bootstrap.min.js"></script>
<script src="js/games.js"></script>

</body>
</html>

All the Ember heavy lifting takes place in js/games.js.

Ember Parts

In order to get Ember up and running, we need some common components:

  • Application – the main Ember application
  • Model – our actual data with methods to get at the information
  • Router – a description of the paths supported by the application and how the app will determine which models to load
  • Routes – how to tell ember which models to load based on the current URL / route
  • Templates – how to actually display the information to the user

Application

We start with the Application. This is easy enough:

App = Ember.Application.create({});

Model

I’ll say little about the model for now. In this case, I am not using Ember Data. Instead, I am using a plain old JavaScript object. I then store the object in the application for easy reference.

All you really need to know is that the methods on the model exist and do what they say:

Store = {
    franchises: Ember.A(),
    defaultFranchise: function() {...},
    get: function(id) {...},
    init: function() {
        if(this.franchises.length == 0) {
            this.franchises.pushObject(App.Franchise.create({
                id: 0,
                title:'Final Fantasy',
                games: Ember.A(),
                defaultGame: function() {...},
                get: function(id) {...},
                init: function() {...}
            }));
            this.franchises.pushObject(App.Franchise.create({...}));
            ...
        });
    }
};

App.Franchise = Ember.Object.extend({});
App.Game = Ember.Object.extend({});

// assign the model to the App for reference
App.GameStore = Store;
App.GameStore.init();

Router

The router will define most of our application. When creating a router, you define the routes with names and paths. Once you have a name of a route, Ember will automatically look for routes and controllers with specific names. So, a route named franchise will have a FranchiseRoute and a FranchiseController. See the naming conventions for more information.

App.Router.map(function() {
    this.resource('franchise', { path:'/franchise/:franchise_id'}, function() {
        this.resource('game', { path: '/game/:game_id' });
    });
});

Here, we’ve defined two routes, a franchise route that Ember will load whenever /franchise is part of the path. An optional franchise ID can also be a part of the path. The second route is under the franchise route. Whenever Ember sees the /franchise/{franchise_id}/game URL, the game route will be loaded.

Routes

Even though we have only defined two routes, there are four routes that we want to define.

  • ApplicationRoute (/) – What happens when the root of the site (/) is visited? The ApplicationRoute is used to add a list of franchises to the controller.
  • IndexRoute (/) – If the ApplicationRoute is only adding a list of franchises, what is getting displayed? Simple, the root of the site will actually be directed to the IndexRoute, which, in this case, will redirect the user to the franchise route with the default franchise.
  • FranchiseRoute (/franchise/{franchise_id}) – Now that we’ve reached the franchise route, we will need to load the model. In this case, we want to take the franchise_id that we defined in the App.Router from the URL and load the specified franchise.
  • GameRoute (/franchise/{franchise_id}/game/{game_id}) – like the FranchiseRoute, this route will pull the game_id from the URL and load the requested game model.

Translating this to code, we get:

App.ApplicationRoute = Ember.Route.extend({
    setupController: function(applicationController) {
        applicationController.set('franchises', App.GameStore.franchises);
    }
});

App.IndexRoute = Ember.Route.extend({
    redirect: function() {
        this.transitionTo('franchise', App.GameStore.defaultFranchise());
    }
});

App.FranchiseRoute = Ember.Route.extend({
    model: function(params) {
        return App.GameStore.get(parseInt(params.franchise_id));
    }
});

App.GameRoute = Ember.Route.extend({
    model: function(params) {
        return this.modelFor('franchise').get(parseInt(params.game_id));
    }
});

Note: a url with both a franchise and a game will pass through the ApplicationRoute, FranchiseRoute, and GameRoute. This is important to understand because each route’s template will also be rendered.

Templates

Back to the HTML, notice above that there is a spot for us to store our templates.

This application has three templates that correspond to the four routes we created earlier:

  • Default template – this template has no ID attribute, so Ember assumes it is for the base application route (/). This URL will trigger both the ApplicationRoute and the IndexRoute. The template will then have access to the franchises property we added above.
  • franchise – this corresponds to the FranchiseRoute above and will be rendered as the default template’s {{outlet}}. It will have access to the franchise loaded as the template’s model implicitly.
  • game – similarly, this template is loaded as the franchise’s {{outlet}} and will have the implicit game model.
<script type="text/x-handlebars">
    <h1>Franchises</h1>
    <ul>
        {{#each franchise in franchises}}
            <li>{{#linkTo 'franchise' franchise}}{{franchise.title}}{{/linkTo}}</li>
        {{/each}}
    </ul>

    {{outlet}}
</script>

<script type="text/x-handlebars" id="franchise">
    <h2>{{title}}</h2>
    <ul>
        {{#each game in games}}
        <li>{{#linkTo 'game' game}}{{game.title}}{{/linkTo}}</li>
        {{/each}}
    </ul>
    {{outlet}}
</script>

<script type="text/x-handlebars" id="game">
    <dl>
        <dt>{{title}}</dt>
        <dd>{{releaseDate}}</dd>
    </dl>
</script>

Again, note that a URL with both a franchise and a game will need to render all three templates as each template will be loaded as an {{outlet}} in each of the parent templates.

Also of note, the templates are each loaded in the order of URL precedence. So, when Ember sees /franchise/2/game/1 it will purposely load the default template with the franchise template in the {{outlet}} and the game template will be loaded in the franchise’s {{outlet}}.

This, of course, is on purpose and is part of a RESTful architecture and design. It also helps tie everything back together. The URL, routes, and templates are (as well as controllers, not covered here) are all linked tightly. This is where Ember’s magic takes place and is the first step towards understanding the framework.

Always Be Refactoring

If there is one thing you can do to improve your coding skills, it would have to be refactoring existing code.

Start with some old code written by someone who didn’t know better (possibly you) – code that doesn’t follow existing conventions - and have at it. Preferably, full unit tests exist for you to verify that the code still works after each change. If you don’t have the tests then creating them is your first step.

Once you have tests in place, you are free to change anything you want without breaking the interface. The benefits of this are many: if you are unfamiliar with the code base, this will get you up to speed quickly; you are able to try new coding styles without harming existing, outside code; and you now have an island of up to date code that can be built upon.

It isn’t reinventing the wheel, but it gets you just as far. You now have a well-defined set of testable requirements with an example implementation that may or may not help you. All your work can happen within the confines of your module or class without affecting others.

The Migration Problem

Being able to write code for programmers has an interesting problem. What do you do when you want to change the API or how a component works?

Typically, in an object oriented approach, you ensure that you are programming to valid interfaces only and that you have abstracted the problem away enough that any change you make is undetectable.

You can’t rely on that happening, though. Sometimes the API changes so dramatically that programming to the old interfaces is like stuffing a round peg into a square hole.

Now you have a migration problem. Version 2 of your API is available and is incompatible with Version 1. What do you do ?

You have a couple options:

  • You can take Salesforce’s approach and keep all your APIs alive, but that means required maintenance on old code and upkeep for any servers you use.
  • You can deprecate and kill off the old API, but you’ll find your current users are rather attached to version 1, if only because migrating to version 2 costs time and resources that could be used to make money.
  • You can create some migration helpers to ease developer’s life while forcing a migration.

It’s the last option that truly speaks to someone writing code for programmers. The slow migration approach will use some rewritten version 1 code that amounts to glue binding the old API to the new API. Developers can then slowly migrate to version 2 while using version 1 in small steps.

This glue code is temporary and goes against most programming principles. It will also be rather ugly. However, as the owner of the API, if you can take on the ugly task required by the migration, all your API users can now avoid the ugly code they would have had to write to begin with.

Hopefully, migrating to the glue code is easier for the developers than completely migrating to version 2. Eventually, you need to kill the old API. This can be done once you know everyone is using the glue code.

Kill off version 1 and then slowly kill off the glue code, which can hopefully be done without your developers needing to do anything beyond flipping a switch.

There is no way out of the ugly code required by a slow migration. However, as an API owner, you can make everyone else’s lives easier by making your life slightly more difficult.

Creating a Reusable URL with Spring RestTemplate

It’s a fact. Spring has a way of simplifying development in a developer-centric way. Spring’s RestTemplate gets us an easy to use REST interface.

We can take it one step further by making the template creation a bit more flexible. What we need is a way to build a template from a known base URL and known parameters with configurable path and parameters.

For instance, a search template could look like: http://api.example.com/search?query={query}&sortOrder={sortOrder}&maxResults={maxResults}&api_key=myKey&format=json

Here, we have a few different requirements needed to build a template:

  • The constant baseUrlhttp://api.example.com
  • The configurable path/search
  • The configurable parameters – query={query}&sortOrder={sortOrder}&maxResults={maxResults}
  • The constant parameters – api_key=myKey&format=json

This is a fairly straight forward implementation which I have found to be very useful.

class RestTemplateUtil {
    private String baseUrl
    private String key
    private String format

    String buildTemplateUrl(String path, Set queryParameters) {
        def builder = new StringBuilder()
        builder.append(this.baseUrl).append(path).append('?')
        queryParameters.each { queryKey ->
            builder.append(queryKey).append('={').append(queryKey).append('}&')
        }
        builder.append('api_key=').append(this.key).append('&format=').append(this.format)
        return builder.toString()
    }

    void setBaseUrl(String baseUrl) {
        this.baseUrl = baseUrl	
    }

    void setKey(String key) {
        this.key = key
    }

    void setFormat(String format) {
        this.format= format
    }
}

Once configured, the developer builds the template from the API path and a Set of parameter names. This Set is easily constructed from a Map of parameters and their values used directly by the RestTemplate.

def templateUtil = new RestTemplateUtil()
templateUtil.baseUrl = 'http://api.example.com'
templateUtil.key = 'myKey'
templateUtil.format = 'json'

def params = ['query':'search terms', 'sortOrder':'asc', 'maxResults':20]
def template = templateUtil.buildTemplateUrl('/search', params.keySet())

def rest = new RestTemplate()
def result = rest.getForObject(template, String, params)
println result

This could be expanded easily by changing the utility class follow the builder pattern or just incorporating the getForObject call directly. However, the above is simple, straight forward and helps reduce code by creating a reusable asset that can easily be leveraged by any code needing RestTemplates

Impossible Machines

Ford Focus Commercial – Oh how I hate you

Honestly, does this sell cars?

What is the argument here? “Don’t you hate it when you have to choose between voice navigation or better than average gas mileage? ‘Cause that’s a thing, right? Adding voice navigation eats up tens of miles per gallon somehow.”

This, of course, is directly analogous to having to decide between sweet or sour chicken: two options where one actually exists as a recipe and the male lead nearly vomits out the other. Which option is the “sour chicken” in this example? It’s the gas mileage, isn’t it?

KH3 on PS4

It was announced yesterday, Kingdom Hearts 3 will be released on the PS4, and I’m a bit disappointed.

I’ve been a fan of the Kingdom Hearts series for a long time now. I even get into the convoluted plots that can’t withstand the slightest internal contradictions (why is it that keychains are the only way to change the keyblade in KH1, but the rest of the series makes it clear that there are hundreds of different keyblades?).

My first introduction to Kingdom Hearts was when my brother gave me the first game as a Christmas present. Neither of us knew much about it other than that it merged Disney characters with Final Fantasy characters. Since we didn’t know much about Final Fantasy, this didn’t explain much.

There was also the fact that I never saw any of the “classic” Disney movies. I still have never seen Cinderella, Peter Pan, Alice in Wonderland, Pinocchio, or many other films used by the Kingdom Hearts franchise.

I played through the first Kingdom Hearts without paying much attention. I liked the action / RPG gameplay which I had never played before, but I wouldn’t have been able to summarize the plot for you.

I had recently purchased a Game Boy Advanced when Chain of Memories came out. Picking it up on a whim, I played through the game on a trip to Duluth. Because of the simple gameplay, the plot really stood out more, and I began to see some inklings of the story.

I played through the first game once more, attempting to understand what was happening and I was drawn in. I’ve always enjoyed the light vs. dark metaphor and Kingdom Hearts did a good job of employing it throughout the plot. This play through, I made it to level 99 with the intent of finally beating Sepheroth (never did beat him).

Afterwards, I was very excited about the next entry in the series. Kingdom Hearts 2 finally came out and I immediately loaded it up after purchasing it, not knowing about the 6 hours of introduction before the title screen appears. After this, I was finally interested in Final Fantasy and have been playing the entire series since (except FFVIII, that game sucks).

Already owning a PSP, I played Birth By Sleep once it was out. Dream Drop Distance was my excuse to purchase a 3DS which also let me play 358/2 Days once I found a used copy (but that disappointing game has kept me from searching for RE: Coded).

With the exception of the handheld spinoffs, the main series games were both on the PS2. After playing through KH2, which came out late in the console’s life, it seemed inevitable that KH3 would be on the PS3. However, instead of announcing the next numbered entry in the series, they kept creating new handheld games.

Rumor had it that the director of KH3 wouldn’t work on the game until Final Fantasy Versus XIII was complete. Versus XIII was announced in 2006 and is now planned to be called Final Fantasy XV instead. 7 years later and it still hasn’t been released.

Now, KH3 has been announced for PS4, skipping an entire generation of consoles. Kingdom Hearts was enough motivation to purchase a $170 handheld with a decent library behind it, but there’s no way it can get me to purchase a $400 console with no other games. I guess I’ll just put it on my “to play” list and pick it up used once the console drops in price.