|
HannibalExamples
The popular Runners and Racers example that illustrates how to use Hannibal for real projects.
Runners and RacersSo we were just reading an interesting post over at The Disco Blog regarding the simplicity of creating web services using Grails. Grails is a very popular framework for creating web applications. After reading that article we were convinced that creating a web service using Grails was indeed simple; of course we wondered how Hannibal stacked up to that ... So we decided to implement that "runners and races" example in Hannibal. Here is how you would do it ... First you need to define your domain objects. Here is the Java interface for a Race domain. package com.marathonracing.domaininterface;
@hannibal.generator.Presentable()
@hannibal.generator.Persistable(nullable=false)
public interface Race
{
@hannibal.generator.Persistable(isPrimaryKey=true)
public String getName();
public Double getDistance();
}And then your Runner interface ... package com.marathonracing.domaininterface;
@hannibal.generator.Presentable()
@hannibal.generator.Persistable(nullable=false)
public interface Runner
{
@hannibal.generator.Persistable(isPrimaryKey=true)
public String getFirstName()
public String getLastName()
@hannibal.generator.Persistable(nullable=false, minimumValue=13)
public Integer getAge();
@hannibal.generator.Persistable(mapTo="Race.name")
public String getRaceName();
}So now that you have defined your interfaces for your domain objects you are now ready to view your web application. Hannibal comes with generic handlers that are called whenever a domain does not have on defined by you. To view these generic pages simply type the following at the command line ... ant hannibal bounce and stand back. When ant is finished point your browser to GET http://localhost:8080/marathonracing/a/race and this will return all available races. Doing a GET (find) to this URI http://localhost:8080/marathonracing/a/race?h.rep=form will return a form that you can use to POST (insert) a new race. Posting the form will automatically redirect your browser to GET a form that can PUT (update) an existing race. To see all the runners in the "CherryBlossom" race simply visit http://localhost:8080/marathonracing/a/race/cherryblossom/runner This will return a list of runners. Creating new runners is as simple as creating a new race. We think this is pretty simple. Understand that along with the above, the autogenerated forms also include free syntactic validation (remember the minimum age of 13 requirement?), as well as free full text indexing for all created resources as well. Full text search is really easy to implement when its done for you. Hannibal allows you do to more sophisticated things as well, like inject semantic validation and business rules as well as declarative security based on the user (subject), action (HTTP method), and the object (domain). All this while developing in server side JavaScript! Read more of this wiki to get a sense of what else Hannibal gets you. We think this is very simple indeed. Runners and Racers Web ServicesSo how would you create web services? Well Hannibal allows you to define your own handlers. Hannibal can find these handlers automatically as long as you follow convention. For the Race domain in the "Marathon "script/javascript" directory in the Hannibal project.... marathonracing/handler/race then create your handler GET_Race.js and place it in that directory. What would GET_Race.js look like? var race = h.get(); CONTENT_CONTEXT.content = (h.isDefined(race) === true) ? race.rdfa() : h.msg404(); That's it. You now have a web service that return an RDFa representation of the race. The logic in GET_Race.js is simple. If the race exists then return it, if it is not found then you return a HTTP 404 message. If you go to this URI http://localhost:8080/marathonracing/a/race/cherryblossom Here is what the Race domain RDFa fragment looks like ul class="marathonracing:race">
<li property="name" class="hannibal:link">
<a href="" rel="hannibal:self" class="hannibal:string">cherryblossom</a>
</li>
<li property="name" class="hannibal:string">cherryblossom</li>
<li property="distance" class="hannibal:double">5</li>
</ul>and if you went to this URI (assuming there is no such race as the "monkey" race) http://localhost:8080/marathonracing/a/race/monkey and here is what the 404 RDFa message fragment would look like <ul class="marathonracing:error"> <li property="message" type="hannibal:string">Resource Not Found</li> <li property="category" type="hannibal:string">404</li> <li property="name" type="hannibal:string">a/race/monkey</li> </ul> Real simple. What if you wanted to create a race? Well in the same directory you put GET_Race.js simply create a handler called POST_Race.js. Here is what it would look like. var [race, errorMap, key] = h.post(); CONTENT_CONTEXT.content = (race.error === false) ? CONTENT_CONTEXT.redirect(h.prepareUri(key)) : h.sem(errorMap); Three lines of JavaScript. Real Simple. Do an HTTP post to this URI http://localhost:8080/marathonracing/a/race and POST_race.js will be automatically executed by Hannibal. If you want a better understanding of how this works read the Wiki on CreatingHandlers. Important!!!
|
Sign in to add a comment