Update: Based on several comments posted on the Google+ Go community, I rewrote the solution presented here. See past the Conclusion section.
Recently, I was asked to write a small program for collecting product promotion information for a large collection of products. Given an input file of product identifiers, the following tasks had to be done:
- read all identifiers from an input file
- for each identifier, fetch product offer information in XML
- parse the offer XML into in a DOM document
- extract all promotions from the offer document
- for each promotion, export its data into a CSV record
A straightforward implementation is to write a function for each task and call them in a nested loop. For this program, I created functions such that the basic flow is quite simple.
Hopwatch is an experimental tool that can help debugging Go programs. Unlike most debuggers, hopwatch requires you to insert function calls at points of interest in your program. At these program locations, you can tell Hopwatch to display variable values and suspend the program (or goroutine). Hopwatch uses Websockets to exchange commands between your program and the debugger running in a HTML5 page.
Using Hopwatch
Basically, there are two functions Display and Break. Calling Display will print the variable,value pairs in the debugger page. Calling Break will suspend the program until you tell the debugger to Resume. The Display function takes one or more pairs of (variable name,value). The Break function takes one or more boolean values to be conditionally. Below is a test example.
package main
import "github.com/emicklei/hopwatch"
func main() {
for i := 0; i < 6; i++ {
hopwatch.Display("i",i)
j := i * i
hopwatch.Display("i",i, "j", j ).Break(j > 10)
hopwatch.Break()
}
}
Starting your Go program that includes a Hopwatch function call waits for a connection to the debugger page.
You can disable Hopwatch by passing the command line parameters -hopwatch false.
In an earlier post, I discussed an example of using plain functions as objects. Today, I investigated solutions for using Methods as objects. As I understand it, Go methods are functions that are “bound” to a named type that is not a pointer or an interface.
package main
import "fmt"
type T struct {
S string
}
func (t T) GetS1() string {
return t.S
}
func (t *T) GetS2() string {
return t.S
}
func main() {
t := T{"hello"}
f := (*T).GetS1
g := (T).GetS1
h := (*T).GetS2
// i := (T).GetS2 // invalid method expression T.GetS2 (needs pointer receiver: (*T).GetS2)
fmt.Printf("%v, %v %v, who is there?", f(&t) ,g(t), h(&t))
}
Run it yourself.
In a previous post, I discussed the design of go-restful which is a package for building REST-style WebServices using the Google Go programming language.
Today, I completed the implementation of that package which provides the basics:
- Creating a WebService with Routes (mapping between Http Request and a Go function)
- Each Route requires information about the Http method (GET,POST,...), URL Path (/users..), Mime-types and the function it binds to
- Functions get passed in a Request and a Response
- The Request is used to access Path and Query parameters , Headers and request content (XML, JSON,...)
- The Response is used to set Status, Headers, and response content
- Both Request and Response can Unmarshal and Marshal objects to and from XML,JSON using the standard packages
All of this can best be illustrated with a small example ; a Webservice for CRUD operations on User objects.
We start by creating the file userservice.go inside its own folder userservice.
package userservice
import (
"github.com/emicklei/go-restful"
"log"
)
type User struct {
Id, Name string
}
Type User represents our domain object.
Today, I played with functions as objects in the Go programming language. If functions are first class citizens in Go then it must be possible to store them in fields of a struct, pass them as arguments to other functions and use them as return values of other functions.
So I visited play.golang.org for putting together a simple program that demonstrates this.
package main
import "fmt"
func CallWith(f func(string), who string) {
f(who)
}
type FunctionHolder struct {
Function func(string)
}
func main() {
holder := FunctionHolder{ func(who string) { fmt.Println("Hello,", who) }}
CallWith(holder.Function,"ernest")
}
- The CallWith function takes a one string parameter function f and a string parameter who. The body of the CallWith function evaluates the function parameter with the string parameter.
- The FunctionHolder is a struct type with a field called Function which must be a function with a string parameter.
- In the main function, a FunctionHolder is created initializing the Function field with a function that prints an Hello message.
- Next in the main function, the CallWith function is called with the Function value of the holder and a string value.
On play.golang.org can run this program yourself
I have been using JAX-RS for many REST-based service implementations in Java.
As part of my journey into the Google Go programming language, I am exploring designs for such REST support using the standard net/http package in Go.
JAX-RS provides a set of Annotation classes which can be used to add meta-data to classes, methods and method arguments. In JAX-RS these annotation are used to specify the mapping between a Http Request to a Java method and its arguments.
I started working on this “yet-another-web-server” project for one of the most important reasons: because its fun. I got inspired for doing this after reading about the Netty framework and all the positive reviews that people write.
My requirements for this server are
- provide a minimal MVC framework that uses renderSnake to render HTML pages
- (distributed) Http session management using JBOSS Infinispan, a modern caching solution
- use Netty , a well-designed fast server framework which I will use for its HTTP support
- components are wired together using Guice, a lean dependency injection library
- support for a minimal feature set to run Web applications
- GET, POST
- Redirects,Forwards
- Sessions, Cookies
- Error Handling (404,500,...)
- Logging using SLF4j
- Basic static content serving
To "eat my own dogfood", I re-implemented the renderSnake website (which is just a Java application) using the renderShark engine.
The project is hosted on googlecode. Have a look at the example project that demonstrates all the features.
For the past month, I have been working on a new iPad Web application that recently was launched at 6hoek.com.
This application provides easy access to the complete product catalog of the Dutch online webshop bol.com.
Because it is targeted to owners of tablet devices such as the Apple iPad, I decided to embrace the upcoming JQuery Mobile framework (JQM), an open-source Javascript library that provides an unified UI to various mobile devices. For producing the HTML markup, I (obviously) choose renderSnake, an open-source HTML component library that promotes writing UI components in Java instead of templates.
rendersnake is a Java library for creating components and pages that produce HTML using only Java. Its purpose is to support the creation of Web applications that are better maintainable, allows for easier reuse, have testable UI components and produces compact HTML in an efficient way.
This blog post explains how to start from a carefully designed rich HTML page and create new or use the components available in the library.
renderSnake is a open-source library for creating components that produce HTML using only Java. By defining Java classes for HTML components and pages you can exploit all the language features (e.g. inheritance, composition, type-checking) and IDE tooling (e.g. refactoring, unit-testing, references search, debugging,…). In addition, renderSnake is designed to produce compact HTML in an memory efficient way.
The "V" in MVC
Basically, renderSnake is responsible for the presentation layer of a Web application. It has no dependencies with an application framework but it does provide classes to integrate with other technologies such as JavaServer Pages and Spring-MVC. Spring-MVC is a popular implementation of the MVC architecture. This pattern isolates "domain logic" (the application logic for the user) from the user interface (input and presentation), permitting independent development, testing and maintenance of each (separation of concerns).
Example
Below is an example of a Spring-MVC based setup of components. ProductListController is a component that is responsible to handling incoming requests. That execution starts by retrieving the Product objects (Model) through a Product Data Access Object. Then a ProductListPage object is created and asked to render itself. Each UI component that is part of the ProductListPage is asked to do the same. The response will have the resulting HTML content.
- missing image /2011/02/spring-mvc-rendersnake.png
Controller
The method below is part of the ProductListController and is called with a prepared HtmlCanvas object that captures the request,response and output writer. Before rendering the page using the HtmlCanvas, all required domain objects are retrieved and made available to the PageContext (Map) of the HtmlCanvas object. Now the HtmlCanvas has all the information needed to perform the rendering phase.
@RequestMapping("/productlist.html")
@ResponseBody
public void showProductListPage(HtmlCanvas html) throws IOException {
html.getPageContext().set("products", this.productListDao.getBestSellersProductList());
html.render(new WebshopLayoutWrapper(new ProductListPage())));
}
View
Using renderSnake, the View layer is implemented by a collection of small, potentially reusable, UI component classes that are composed into Page objects that represent HTML content.
Class Head is an example UI component responsible for rendering the head section of every HTML page. It implements the Renderable interface and uses the HtmlCanvas parameter object for rendering. The HtmlCanvas object has methods of all elements (tags) in order to write HTML content. Using the HtmlAttributesFactory, you can specify the attributes for each HTML tag. By convention, the method source has a format that uses indentation to see the nesting of tags. This is not required but improves its readability.