NextBeer, a sample OpenApi application for T-Mobile

Last summer I responded to a request for proposal from T-Mobile in Poland. This rather large telco, wanted to share its services in an easy way on-line, so that every little private developer could use them, a bit like Facebook/Amazon does. We got the job, though the news came so late, I had already started another project (for yet another telco), and as an effect, could not participate in the one for T-Mobile.

The project has a fitting name: OpenApi, because that’s what it really is. An open API for everyone who wants to use it. I’ve heard there was an initiative, to build a common API for all telcos, quite a smart move which would ease creating applications even further, but for now it’s custom designed and build.

My friends finished coding a portal for developers, and I was asked to write a sample application. It made a lot of sense to me: the guys deeply in the guts of the system, should not create samples – their perspective is different to real users. I, on the other hand, while knowing what the system is supposed to do (I wrote the proposal together with Piotr Jagielski), haven’t seen in yet.

And so, a sample application was born, created in Grails, though a bit Java-style (I wanted to keep it familiar to all those Java/C# folks, who know no Groovy).

The user story is simple. It’s Friday, late evening, you are sitting in a pub, together with your friends, but the place is going to be closed at 10pm, which is very unfortunate, as the sweet brunette on your right has just noticed your presence.

You need to move the party forward, to another place, so you take your shiny, last-gen iSmartphone from your pants, only to find out its battery has died. Running all those apps of your design was really demanding.

So the sweet brunette on your right, pulls her old, dumb Nokia, and send an sms. Few minutes later she gets one back, with addresses and phone numbers of all the pubs in 3km range. That’s how far she can get on her high hills.

Your party is saved. Your sweet brunette may be truly yours someday. The application which responded to the sms and saved the day, is the sample application I wrote, using OpenAPI and Google Places. It’s called: NextBeer.

One picture is worth thousand words, so here is a sequence diagram for the whole thing.

You can find the code on github: https://github.com/jakubnabrdalik/nextbeer

I won’t go into details, the code is self documenting, and there is even a nice tutorial for all those who know nothing of Grails (though it’s in Polish, as that was the target audience of my example).

If you want to register to OpenAPI, to write your own, go here: https://developers.t-mobile.pl

Hope that saves you a nice brunette one day.

You May Also Like

mount.ntfs high cpu ubuntu

My computer suffers from sudden and continous hard drive load strokes. Sometimes it lasts for a few minutes and hence work is impossible because everything goes very slow.I'm trying to locate the cause because it makes me nervous :)Today I found one of...

Simple trick to DRY your Grails controller

Grails controllers are not very DRY. It's easy to find duplicated code fragments in default generated controller. Take a look at code sample below. It is duplicated four times in show, edit, update and delete actions:

class BookController {
def show() {
def bookInstance = Book.get(params.id)
if (!bookInstance) {
flash.message = message(code: 'default.not.found.message', args: [message(code: 'book.label', default: 'Book'), params.id])
redirect(action: "list")
return
}
[bookInstance: bookInstance]
}
}

Why is it duplicated?

There is a reason for that duplication, though. If you move this snippet to a method, it can redirect to "list" action, but it can't prevent controller from further execution. After you call redirect, response status changes to 302, but after method exits, controller still runs subsequent code.

Solution

At TouK we've implemented a simple trick to resolve that situation:

  1. wrap everything with a simple withStoppingOnRender method,
  2. whenever you want to render or redirect AND stop controller execution - throw EndRenderingException.

We call it Big Return - return from a method and return from a controller at once. Here is how it works:

class BookController {
def show(Long id) {
withStoppingOnRender {
Book bookInstance = Book.get(id)
validateInstanceExists(bookInstance)
[bookInstance: bookInstance]
}
}

protected Object withStoppingOnRender(Closure closure) {
try {
return closure.call()
} catch (EndRenderingException e) {}
}

private void validateInstanceExists(Book instance) {
if (!instance) {
flash.message = message(code: 'default.not.found.message', args: [message(code: 'book.label', default: 'Book'), params.id])
redirect(action: "list")
throw new EndRenderingException()
}
}
}

class EndRenderingException extends RuntimeException {}

Example usage

For simple CRUD controllers, you can use this solution and create some BaseController class for your controllers. We use withStoppingOnRender in every controller so code doesn't look like a spaghetti, we follow DRY principle and code is self-documented. Win-win-win! Here is a more complex example:

class DealerController {
@Transactional
def update() {
withStoppingOnRender {
Dealer dealerInstance = Dealer.get(params.id)
validateInstanceExists(dealerInstance)
validateAccountInExternalService(dealerInstance)
checkIfInstanceWasConcurrentlyModified(dealerInstance, params.version)
dealerInstance.properties = params
saveUpdatedInstance(dealerInstance)
redirectToAfterUpdate(dealerInstance)
}
}
}