A client the following requirements
"Build a web based client entry tracking application with API support on Google App Engine"
I followed the usual route of doing a preliminary use case analysis and out came the top level idea of the project. The use case were:
- CRUD Client entry
- Auth using google UserService
- REST based API to expose "Client Entry" as a resource.
The technology platform/libraries choosen to implement the above system:
- Eclipse with Google Plugin
- Google App Engine SDK 1.3.7
- GWT 2.1M3 for client application
- Restlet 2.0.x for REST implementation
- MVP4G for MVP implementation in GWT.
Current application can be browsed here http://cloudresidentapi.appspot.com/
The first thing i did was to put a class diagram which reflects the entire application domain model. See a snapshot below.
I am using StartUML diagraming tool to do the UML diagram above.
I divided the project into 2 major parts.
- The API part, which will allow any user with proper credentials to access the entries and its details in XML or JSON.
The urls should be of the form http://someserver/myapp/api/entries to get all the entries
For getting individual entry http://someserver/myapp/api/entries/{clientname}
where, {clientname} is variable to identify the client by just his/her name.
- The client part, that uses the api for various operations on the entities
First I proceeded on to build the REST api that will be used by the client app. Using Google plugin, build a google web application, making sure of the various framework versions. Add the Restlet jars in WEB-INF/lib dir of the web application.
To do all the CRUD operations i made 2 Resources (as per the Restlet API).
EntitiesResource and EntityResource. Below is the relevant code.
The Restlet application class to manage the resource and its URL mappings
MyApplication.java
@Override
public Restlet createInboundRoot() {
System.setProperty("javax.xml.transform.TransformerFactory", "com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl");
Router r=new Router(getContext());
//r.attachDefault(HelloResource.class);
r.attach("/hello", HelloResource.class);
r.attach("/entries",EntriesResource.class);
r.attach("/entries/{entry}",EntryResource.class);
MapVerifier mv=new MapVerifier();
mv.getLocalSecrets().put("scott", "tiger".toCharArray());
ChallengeAuthenticator ca=new ChallengeAuthenticator(getContext(), ChallengeScheme.HTTP_BASIC, "Hello resource gaurd");
ca.setVerifier(mv);
ca.setNext(r);
return ca;
}
The web.xml servlet mappings pointing to the MyApplication class.
<servlet>
<servlet-name>RestletServlet</servlet-name>
<servlet-class>org.restlet.ext.servlet.ServerServlet</servlet-class>
<init-param>
<param-name>org.restlet.application</param-name>
<param-value>com.anansu.api.MyApplication</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>RestletServlet</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
The implementation of EntitiesResource.java,
This is to respond to url like
http://someserver/myapp/api/entries
@Get("xml")
public Representation toXml(){
DomRepresentation dr=null;
try {
dr = new DomRepresentation(MediaType.TEXT_XML);
Document d=dr.getDocument();
Element r = d.createElement("items");
d.appendChild(r);
for (Entry item : getItems().values()) {
Element eltItem = d.createElement("item");
Element eltId=d.createElement("id");
eltId.appendChild(d.createTextNode(String.valueOf(item.getId())));
eltItem.appendChild(eltId);
Element eltName = d.createElement("name");
eltName.appendChild(d.createTextNode(item.getName()));
eltItem.appendChild(eltName);
Element eltEmail = d.createElement("email");
eltEmail.appendChild(d.createTextNode(item.getEmail()));
eltItem.appendChild(eltEmail);
Element eltMsg=d.createElement("msg");
eltMsg.appendChild(d.createTextNode(item.getMessage()));
eltItem.appendChild(eltMsg);
r.appendChild(eltItem);
}
d.normalizeDocument();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return dr;
}
EntityResource.java
Responds to url like http://someserver/myapp/api/entries/jack
@Get
public Representation toJson(){
JsonRepresentation jr=new JsonRepresentation(this.entry);
return jr;
}
Notice that one this output is in JSON and not in XML.
Before implementing the POST, i needed to make a web form to actually POST the client info to the API. So i then proceeded to make the GWT client.
First i selected a design template and then proceeded on make the UiBinder version of the design template.