Dropwizard From the Start — Part 2: Building a UI Using Mustache
If you’ve been following along with my first two articles, I am on a journey of discovery through the land of Dropwizard. I’m finding out what all the fuss is about, and whether I can learn to like frameworks again. We had a simple chat system working which was purely JSON on top of REST. The next logical thing is to build a UI.
Join the DZone community and get the full member experience.
Join For FreeIf you’ve been following along with my first two articles, I am on a journey of discovery through the land of Dropwizard. I’m trying to discover what all the fuss is about, and whether I can learn to like frameworks again. We had a simple chat system working which was purely JSON on top of REST. The next logical thing is to build a UI.
Along with everything that comes in Dropwizard core (Jetty, Jersey, and Jackson), there’s a whole heap of extra stuff Dropwizard throws in as optional, one of which being the *dropwizard-views* packages. These give the developer access to both Freemarker and Mustache templating engines with a little bit of Dropwizard magic over the top.
Mustache
I’ve always been a big fan of Handlebars, which is effectively a derivative of Mustache. It’s really simple to use; you simply write plain old HTML, but where you want variables from Java land you simply wrap them in double curly braces. You’re fairly limited to object access and not much more, so the UIs end up clean; no JSP-esque UI logic hell here.
The HTML/mustache mashup is a template which is compiled against a Java class, where the knowledge comes from.
<html>
<head></head>
<body>
<div class="top">
<div class="user">Logged in as {{currentUser}}</div>
</div>
</body></html>
Compiled against:
public class MyView{
public String getCurrentUser() {
return “Bobby”;
}
]
Will result in:
<html>
<head></head>
<body>
<div class="top">
<div class="user">Logged in as Bobby</div>
</div>
</body></html>
Easy peasy! Mustache has basic syntax for going through loops and I’ve found it to be simple to use and sufficiently powerful. It’s apparently being used by Twitter according to the Mustache Github page, so it should hopefully be sufficiently performant.
Where I’ve been reasonably impressed is the extra value that Dropwizard adds. Normal usage requires you to create a Mustache factory, compile the template and write the data out from it; whilst not particularly onerous, it’s extrenuous boiler plate would be nice to be rid of. Fortunately, Dropwizard takes care of it. By returning a class that extends a Dropwizard View class, it will automatically render the page.
I want a single page for my UI: a list of people I’m chatting with on the left and the current chat on the right. This means my view needs a list of all my chats, plus the current chat and the usernames to allow me to submit chats.
public class ChatroomView extends View {
private final List<ChatView> allChatsForThisUser;
private final String currentUser;
private final Chat currentChat;
private final String otherUser;
public ChatroomView(String currentUser, String otherUser, Chat currentChat, List<ChatView> allChatsForThisUser) {
super("chat.mustache");
this.currentUser = currentUser;
this.otherUser = otherUser;
this.currentChat = currentChat;
this.allChatsForThisUser = allChatsForThisUser;
}
public List<ChatView> getChats(){
return allChatsForThisUser;
}
public Chat getCurrentChat() {
return currentChat;
}
public String getCurrentUser() {
return currentUser;
}
public String getOtherUser() {
return otherUser;
}
}
This is a simple POJO. The only interesting parts are “extends View” which we discussed before, and the first line of the constructor. Here, we tell the superclass the name of the template which we wish to compile, in our case chat.mustache. Here’s the full template:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="/assets/css/skeleton.css"/>
<link rel="stylesheet" href="/assets/css/main.css"/>
</head>
<body>
<div class="top">
<div class="user">Logged in as {{currentUser}}</div>
</div>
<div class="container">
<row>
<div class = "three columns">
<h1>Chats</h1>
<ul>
{{#chats}}<li><a href="/chat/{{userOne}}/{{userTwo}}">{{userTwo}}</a></li>{{/chats}}
</ul>
</div>
<div class = "nine columns">
{{#currentChat}}
<h1>Chat between {{currentUser}} and {{otherUser}}</h1>
{{#chat}}
{{.}}<br/>
{{/chat}}
<br>
<form method="post" action="/chat/{{currentUser}}/{{otherUser}}">
<textarea name="message"></textarea>
<br/><button>Submit</button>
</form>
{{/currentChat}}
</div>
</row>
</div>
</body>
</html>
The only new syntax can be seen here:
{{#chat}}
{{.}}<br/>
{{/chat}}
Using #chat allows us to loop through all of the objects in the field “chat”. The {{.}} syntax is simply for using “this”; if instead of a String we had a complex object we could just call the fields on that object here.
@Path("/chat/{userOne}/{userTwo}")
@Produces({MediaType.TEXT_HTML})
public class ChatResource {
@GET
public ChatroomView chatBetween(@PathParam("userOne") final Optional<String> userOne,
@PathParam("userTwo") final Optional<String> userTwo) {
By modifying the return type in our ChatroomResource to be our new view, our mustache template is correctly rendered.
I had to refactor the code somewhat to get everything working. I’d originally allowed the userOne/userTwo of the chat object to be in any order which reeked havok on the views. As a result, I created a ChatView object which represents each chat from the perspective of the “logged in” user.
And for My Next Trick
Hopefully, you were screaming “but what about the REST API? You’ve just killed it in favour of your view!” I was certainly concerned, until I discovered a lovely little trick in Dropwizard. It is possible to specify more than one type in the “produces” field. In this case the default is HTML, but if the client specifies an accept header of JSON then Dropwizard will use Jackson to serialise the view. We can have a single API point return HTML or JSON depending on the clients wish! This is so cool.
@Path("/chat/{userOne}/{userTwo}")
@Produces({MediaType.TEXT_HTML, MediaType.APPLICATION_JSON})
public class ChatResource {
Here’s a picture of the call from postman, the exact same URL, just with the JSON request header.
At the moment, the result isn’t great (the chat’s returned twice!) but that can be easily optomized.
Thoughts and Concerns
I must admit that overall I’ve been quite impressed so far. It’s been pretty quick to get going to build an application and for the most part it has all kind of “just worked”. However, I have struggled with poor documentation on this part. Dropwizard refers to the Mustache Java docs, which are really pretty poor at this juncture. There’s literally nothing on the Dropwizard additions to mustache; this makes it near impossible to figure out how to do some of the deeper integrations in the Mustache Java documentation in Dropwizard because it’s been abastracted away. On a simple app like this it’s not been too much of an issue but it would make me nervous going into a bigger application. However, there’s literally nothing tying you to the Dropwizard version. I could easily just use the standard library if it were to become a big problem.
Next up for the application is login and persistance. After this, it’ll be a fully functional chat application; it still does full page refresh for each message which isn’t ideal but that’s certainly something to improve.
You can view the full code at https://github.com/samberic/wizchat.
Please leave comments in the box, and follow me on Twitter @SambaHK for updates and whimsy.
Opinions expressed by DZone contributors are their own.
Comments