Monday 2 January 2012

Create Spring REST service for Google App Engine in 15 minutes

Here's how you setup a REST service deployed in the Google App Engine cloud in 15 minutes. The use case in this example is a highscore backend service for my Android game Othello Legends.

Requirements:
We want to create a REST interface for these resources representing a highscore service.


GET http://myapp.appspot.com/api/highscores/
Fetch all applications backed by the highscore service since we want to reuse this for multiple games.

GET http://myapp.appspot.com/api/highscores/myappname
Fetch a sorted listed of highscores for a particular application myappname.

POST http://myapp.appspot.com/api/highscores/myappname
Post a potential new highscore to service. If it makes it to the highscore list it will be saved in database. The data will be sent as query parameters.


Ingredients of the solution:
Google App Engine runs Java and Python. This example will use the Java infrastructure.
So what we'll do is to create a standard Java J2EE web application built for deployment in App Engine backed by a simple DAO to abstract the Google BigTable databases. By using Spring REST together with Jackson we can communicate with JSON in a RESTful manner with minimum effort.

Sounds complicated? Not at all, here's how you do it!

Prerequisities:
REST Implementation:

So to create an App Engine web app, click the New Web Application Project icon. Deselect Google Web Toolkit if you don't intend to use it.

Now, we're going to use Spring REST for the REST heavy weight lifting. Download Spring Framework 3 or later from http://www.springsource.org/download. While at it, download the Jackson JSON library from http://jackson.codehaus.org/. Put the downloaded jars in the /war/WEB-INF/lib/ folder and add them to the classpath of your web application.

Now, to bootstrap Spring to handle your incoming servlet requests you should edit the web.xml file of your web application found in war/WEB-INF/.




   api
   
      org.springframework.web.servlet.DispatcherServlet
   
   1

  

   api
   /api/*



   index.html



That will put Spring in charge of everything coming in under path /api/*. Spring must now which packages to scan for Spring annotated classes. We add a Spring configuration file for this and also add some Spring/Jackson config for specifying how to convert from our Java POJOs to JSON. Put this stuff in a file called api-servlet.xml in war/WEB-INF.


 

 
  
   
    
   
  
 

 

 
  
   
    
   
  
  
  
   
    
   
  
 




Without going into detail, this config pretty much tells Spring to convert POJOs to JSON as default using Jackson for servlet responses. If you're not interested in the details just grab it, but you must adjust the <context:component-scan base-package="se.noren.othello" /> to match your package names.

Now to the fun part, mapping Java code to the REST resources we want to expose. We need a controller class to annotate how our Java methods should map to the exposed HTTP URIs. Create something similar to

import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

/**
 * Controller for Legends app family highscore services.
 */
@Controller
@RequestMapping("/highscores")
public class LegendsHighScoreController {
 private static final long serialVersionUID = 1L;

 @Autowired
 HighScoreService highScoresService;

 /**
  * @return Fetch all registered applications in the highscore database.
  */
 @RequestMapping(value = "/", method = RequestMethod.GET)
 public ModelAndView getAllApplications() {
  List<String> allApplications = highScoresService.getAllApplications();
  return new ModelAndView("highScoresView", BindingResult.MODEL_KEY_PREFIX + "applications", allApplications);
 }
 
 /**
  * Fetch all highscores for a particular application.
  * @param application Name of application
  * @return
  */
 @RequestMapping(value = "/{application}", method = RequestMethod.GET)
 public ModelAndView getAllHighScores(@PathVariable String application) {
  List<HighScore> allHighScores = highScoresService.getAllHighScores(application);
  return new ModelAndView("highScoresView", BindingResult.MODEL_KEY_PREFIX + "scores", allHighScores);
 }
 
 /**
  * Add a new highscore to the database if it makes it to the high score list.
  * @param application Name of application
  * @param owner Owner of the highscore
  * @param score Score as whole number
  * @param level Level of player reaching score.
  * @return The created score.
  */
 @RequestMapping(value = "/{application}", method = RequestMethod.POST)
 public ModelAndView addHighScores(@PathVariable String application,
                             @RequestParam String owner,
                             @RequestParam long score,
                             @RequestParam long level
                             ) {
  
  HighScore highScore = new HighScore(owner, score, application, new Date().getTime(), level);
  highScoresService.addHighScores(highScore);
  return new ModelAndView("highScoresView", BindingResult.MODEL_KEY_PREFIX + "scores", highScore);
 }
}


So what's the deal with all the annotations? They're pretty self explanatory once you start matching the Java methods to the three HTTP REST URIs we wanted to create, but in short:

  • @Controller - The usual Spring annotation to tell Spring that this is a controller class that should be managed by the Spring container. All RESTful stuff is contained within the this class.
  • @RequestMapping("/highscores") - This means that this controller class should accept REST calls under the path /highscores. Since we deployed the servlet under servlet mapping /api in the web.xml this means all REST resources resides under http://host.com/api/highscores
  • @Autowired HighScoreService highScoresService - Our backing service class to do real business logic. Agnostic that we're using a RESTful front.
  • @RequestMapping(value = "/{application}", method = RequestMethod.GET) public ModelAndView getAllHighScores(@PathVariable String application) -  A method annotated like this creates a REST resource /api/highscores/dynamicAppName where the value given for dynamicAppName is given via the path variable application. The request method specifies that this Java method will be called if this URI is requested via HTTP GET. All ordinary HTTP verbs are supported.
  • @RequestParam String owner - If you wish to pass query parameters like myvar1=foo&myvar2=bar you can use the request param annotation.
  • The Java class returned in the ModelAndView response will be automatically marshalled to JSON by Jackson on the same structure as the Java POJO.
Database
Google App Engine uses the Google BigTables behind the scenes to store data. You can abstract this by using the standard JPA annotations on your POJOs. The similar JDO standard can be used as well. I've used JDO in previous projects and it works very well. For this simple server application we will however use the query language to directly access the document database. Here's the code for the first method to fetch all highscores for a particular Legends application. The database can filter and sort via API methods in the query.


@Service
public class HighScoreServiceImpl implements HighScoreService {

 @Override
 public List<HighScore> getAllHighScores(String application) {
  ArrayList<HighScore> list = new ArrayList<HighScore>();
  DatastoreService datastore = DatastoreServiceFactory
    .getDatastoreService();

  // The Query interface assembles a query
  Query q = new Query("HighScore");
  q.addFilter("application", Query.FilterOperator.EQUAL, application);
  q.addFilter("score", FilterOperator.GREATER_THAN_OR_EQUAL, 0);
  q.addSort("score", SortDirection.DESCENDING);

  // PreparedQuery contains the methods for fetching query results
  // from the datastore
  PreparedQuery pq = datastore.prepare(q);

  for (Entity result : pq.asIterable()) {
   String owner = (String) result.getProperty("owner");
   Long date = (Long) result.getProperty("date");
   Long score = (Long) result.getProperty("score");
   Long level = (Long) result.getProperty("level");
   list.add(new HighScore(owner, score, application, date, level));
  }

  return list;
 }


That's pretty much it. Run the project locally by right-clicking it and choose Run As -> Web application. Once you are ready to go live create a cloud application by going to https://appengine.google.com/ and Create new application

Now in Eclipse, right click on your project and choose Google -> Deploy to Google App Engine.
You will be asked to supply the name you created in the App Engine administration interface. Wait a few seconds and the application will be deployed in the cloud.

149 comments:

  1. can you give a little more info to a newbie on how to add the spring and jackson (Put this stuff in a file called api-servlet.xml in war/WEB-INF.) I am on the back side of the learning curve here. or maybe I missed something

    ReplyDelete
    Replies
    1. Hi! Not sure which part you mean? If it's the configuration that confuses you. It's really simple, you put the xml above (<beans xmlns:context ... etc) in a file called api-servlet.xml inside your web application java project. If the web app is created via the Eclipse plugins you should already have a directory structure according to the Java servlet specification. And therefore a folder called WEB-INF. Put the file in that folder, et voila! Good luck

      Delete
  2. Hi Johan,

    Am following on your tutorial am am kind of lost here.

    Where is the class HighScore.java in the method
    public List getAllHighScores under the class HighScoreServiceImpl.java

    Also where are the method implementations of highScoresService.getAllApplications(); and highScoresService.getAllHighScores(application); under the class LegendsHighScoreController.java

    Your tutorial is nice but it is incomplete as it has missing parts.

    I would really appreciate your help on this.

    Am from Nairobi,Kenya.

    ReplyDelete
  3. Hi, the HighScore is a simple POJO according to the constructor demonstrated in the example and the other service backends are pretty much the same as the service getAllHighScores() I described. If you wish to know more about the database APIs against Google App Engine check out the documentation at http://code.google.com/intl/sv-SE/appengine/docs/java/datastore/overview.html and you find more advanced ways to make queries.

    ReplyDelete
  4. Hi Johan,
    I managed to recreate the HighScore POJO as a Persistable JDO object and successfully deployed it.I also created the methods in the controlled that i was asking you.

    However am now getting a new error as follows:
    WARNING: No file found for: /myappname/api/highscores

    I cannot be able to consume any service.Any idea what this is?

    ReplyDelete
    Replies
    1. Sounds like your servlet mappings are wrong if you get http 404. Pls check in your web.xml what servlet mapping you have set for the dispatcher servlet. If you have done according to the example above and used "api", your services should reside at localhost:9080/api/highscores/yourappname

      Delete
  5. Hey Johan, thanks for the tutorial, it would be really useful if you would attach all the sourcecode including the imports and all files. For noobs like me its easier to understand and then i dont have to write that POJO myself haha :) really i dont exactly know which import u are using for the Entity object for example, i guess its javax.persistence but since im a noob i have enough guesswork todo :)

    ReplyDelete
  6. Oh and i dont know which of the libs of the spring framework are needed, so im using all now :P same for jackson, jackson all is needed?

    ReplyDelete
  7. Hey its me again the anonymous appengine noob, it would be cool if you could also provide the code how you access this from your android application. Do you have to deserialize the model object you are using in android yourself to use it for an addHighscore call? or do you use Jackson? What if i want to post a byte[]?? no problemo?? im new to jackson also :/ Except for my gratefulness all i can do is provide you with a five star rating for ur game!

    ReplyDelete
    Replies
    1. Hi again! No you don't need to do it manually. I couldn't make Jackson work on Android which would had been my first choice. Fortunately there are a bunch of JSON marshallers. And there are even stuff coming with the Android default libraries. I used the org.json.JSONObject which is in the core libs. Nice and easy API for my purposes. I used Apache HttpClient for handling the http connections and JSONObject for marshalling between objects and strings. Here is my adapter class for this if you want inspiration. http://pastebin.com/em1vuU01
      Good luck!

      Delete
  8. Why do you use the http://jackson.codehaus.org/ instead of other (e.g. gson from google).
    can i do the same example without the JSON library and mapping (i didn't really get the POJOs translation to JSON)

    ReplyDelete
    Replies
    1. I used Jackson since that's what I'm familiar with. You could substitute with whatever library I guess, but maybe you need to write some glue code if the library is not supported by Spring. Don't know about gson.

      Delete
  9. Hi Johan
    I'm trying to get your example to work with Spring 3.1 and it seems the syntax has changed.
    It's complaining about and tags in the api-servlet.xml.
    Can you post the new file?

    org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 16 in XML document from ServletContext resource [/WEB-INF/api-servlet.xml] is invalid; nested exception is org.xml.sax.SAXParseException: cvc-complex-type.2.4.a: Invalid content was found starting with element 'bean'. One of '{"http://www.springframework.org/schema/context":include-filter, "http://www.springframework.org/schema/context":exclude-filter}' is expected.

    Thx

    ReplyDelete
  10. Or let me know what version of Spring you've used since I've tried 3.1 and 3.0.7 and both are failing with exceptions during the application startup due to issue with declaration of tag.

    Amir

    ReplyDelete
    Replies
    1. If I remember correctly I used Spring 3.0.5. Hope you'll find the mismatch, cheers!

      Delete
  11. Wheres the rest of the code? what a waste of time.

    ReplyDelete
  12. Fucking waste of time with this incomplete code ¬¬ There's no HighScore.java, no addHighScores method....

    ReplyDelete
    Replies
    1. Sorry to waste your time mate, the complete code is available at https://github.com/johannoren/OthelloLegendsBackend

      Delete
  13. This information is impressive; I am inspired with your post writing style & how continuously you describe this topic. After reading your post, thanks for taking the time to discuss this, I feel happy about it and I love learning more about this topic.android development course fees in chennai | android app development training in chennai

    ReplyDelete
  14. I simply want to give you a huge thumbs up for the great info you have got here on this post.
    Click here:
    angularjs training in bangalore
    Click here:
    angularjs training in pune

    ReplyDelete
  15. All the points you described so beautiful. Every time i read your i blog and i am so surprised that how you can write so well.
    Blueprism training in Chennai

    Blueprism training in Bangalore

    Blueprism training in Pune

    Blueprism online training

    ReplyDelete
  16. All the points you described so beautiful. Every time i read your i blog and i am so surprised that how you can write so well.
    Blueprism training in Chennai

    Blueprism training in Bangalore

    Blueprism training in Pune

    Blueprism online training

    ReplyDelete
  17. Really great post, I simply unearthed your site and needed to say that I have truly appreciated perusing your blog entries.
    python training in pune
    python online training
    python training in OMR

    ReplyDelete
  18. I simply wanted to write down a quick word to say thanks to you for those wonderful tips and hints you are showing on this site.
    Blueprism training in marathahalli

    Blueprism training in btm

    Blueprism online training

    ReplyDelete
  19. Hmm, it seems like your site ate my first comment (it was extremely long) so I guess I’ll just sum it up what I had written and say, I’m thoroughly enjoying your blog. I as well as an aspiring blog writer, but I’m still new to the whole thing. Do you have any recommendations for newbie blog writers? I’d appreciate it.

    AWS Interview Questions And Answers

    AWS Training in Bangalore | Amazon Web Services Training in Bangalore

    AWS Training in Pune | Best Amazon Web Services Training in Pune

    Amazon Web Services Training in Pune | Best AWS Training in Pune

    AWS Online Training | Online AWS Certification Course - Gangboard

    ReplyDelete
  20. I would really like to read some personal experiences like the way, you've explained through the above article. I'm glad for your achievements and would probably like to see much more in the near future. Thanks for share.

    Data Science course in rajaji nagar | Data Science with Python course in chenni
    Data Science course in electronic city | Data Science course in USA
    Data science course in pune | Data science course in kalyan nagar

    ReplyDelete
  21. Great post! I am actually getting ready to across this information, It’s very helpful for this blog.Also great with all of the valuable information you have Keep up the good work you are doing well.

    angularjs Training in bangalore

    angularjs Training in chennai

    python training in pune

    python training institute in chennai

    python training in Bangalore

    ReplyDelete
  22. Superb.. Really it is an amazing article I had ever read. I hope it will help a lot for all. Thank you so much for this amazing post.
    lg mobile service center in chennai
    lg mobile service center
    lg mobile service chennai

    ReplyDelete
  23. I have gone through your blog, it was very much useful for me and because of your blog, and also I gained many unknown information, the way you have clearly explained is really fantastic. Kindly post more like this, Thank You.
    mobile service centre
    mobile service center in chennai
    mobile service center chennai
    mobile service centre near me
    mobile service centre chennai
    best mobile service center in chennai

    ReplyDelete
  24. Inspiring writings and I greatly admired what you have to say , I hope you continue to provide new ideas for us all and greetings success always for you.
    Keep update more information..
    moto service centre chennai
    moto service center
    motorola service center
    motorola service center near me
    motorola mobile service centre in chennai

    ReplyDelete
  25. Amazing article. Your blog helped me to improve myself in many ways thanks for sharing this kind of wonderful informative blogs in live. I have bookmarked more article from this website. Such a nice blog you are providing.
    oneplus mobile service center in chennai
    oneplus mobile service center
    oneplus mobile service centre in chennai

    ReplyDelete
  26. Your blog’s post is just completely quality and informative. Many new facts and information which I have not heard about before. Keep sharing more blog posts.
    lg mobile service center in chennai
    lg mobile service center
    lg mobile service chennai
    lg mobile repair

    ReplyDelete
  27. This is the exact information I am been searching for, Thanks for sharing the required infos with the clear update and required points.
    oppo service centres in chennai
    oppo service center velachery
    oppo service center in vadapalani
    oppo service center in porur

    ReplyDelete
  28. I am obliged to you for sharing this piece of information here and updating us with your resourceful guidance. Hope this might benefit many learners. Keep sharing this gainful articles and continue updating us.
    motorola service center near me
    motorola mobile service centre in chennai
    moto g service center in chennai

    ReplyDelete
  29. A very nice guide. I will definitely follow these tips. Thank you for sharing such detailed article. I am learning a lot from you.
    angularjs online training

    apache spark online training

    informatica mdm online training

    devops online training

    aws online training

    ReplyDelete
  30. Thanks For Sharing The information The Information Shared Is Very Valuable Please Keep Updating us The Information shared Is Very Valuable Python Online Course Data Science Online Course Aws Online Course

    ReplyDelete
  31. Attend The Python training in bangalore From ExcelR. Practical Python training in bangalore Sessions With Assured Placement Support From Experienced Faculty. ExcelR Offers The Python training in bangalore.
    python training in bangalore

    ReplyDelete
  32. This comment has been removed by the author.

    ReplyDelete
  33. nice blog
    get best placement at VSIPL

    get digital marketing services
    web development services
    seo network point

    ReplyDelete
  34. Thank you for providing this kind of useful information,I am searching for this kind of useful information; it is very useful to me and some other looking for it. It is very helpful to who are searching python Training.python training in bangalore

    ReplyDelete
  35. I gathered a lot of information through this article.Every example is easy to undestandable and explaining the logic easily.mulesoft training in bangalore

    ReplyDelete
  36. inking is very useful thing.you have really helped lots of people who visit blog and provide them use full information.sccm training in bangalore

    ReplyDelete
  37. thanks i found my solution by reading through this blog..

    aws online training

    ReplyDelete
  38. Thank you so much for the great and very beneficial stuff that you have shared with the world...

    Become an Expert In DBA Training in Bangalore! The most trusted and trending Programming Language. Learn from experienced Trainers and get the knowledge to crack a coding interview, @Bangalore Training Academy Located in BTM Layout.

    ReplyDelete
  39. Very interesting, good job and thanks for sharing such a good blog.

    Real Time Experts Training Center is one of the Best SAP PP Training Institutes in Bangalore with 100% placement support. SAP Production Planning training in Bangalore provided by sap pp certified experts and real-time working professionals with handful years of experience in real time sap pp projects.

    ReplyDelete
  40. I can’t imagine that’s a great post. Thanks for sharing.

    Looking for Salesforce CRM Training in Bangalore, learn from eTechno Soft Solutions Salesforce CRM Training on online training and classroom training. Join today!

    ReplyDelete
  41. This comment has been removed by the author.

    ReplyDelete

  42. I am obliged to you for sharing this piece of statistics
    here and updating us together with your inventive steerage.
    sd movies point

    ReplyDelete
  43. Thanks for sharing such an useful and nice info...keep on posting such an useful info...

    data scientist training

    data science tutorial for beginners

    ReplyDelete
  44. This post is really nice and informative. The explanation given is really comprehensive and useful.... cognos training online

    ReplyDelete
  45. This is so elegant and logical and clearly explained. Brilliantly goes through what could be a complex process and makes it obvious.

    aws courses in bangalore
    aws training

    ReplyDelete
  46. This is so elegant and logical and clearly explained. Brilliantly goes through what could be a complex process and makes it obvious...

    oracle erp training

    ReplyDelete
  47. Pretty article! I found some useful information in your blog, windows azure training it was awesome to read, thanks for sharing this great content to my vision, keep sharing.

    ReplyDelete
  48. The knowledge of technology you have been sharing thorough this post is very much helpful to develop new idea. here by i also want to share this.thanks a lot guys.
    Ai & Artificial Intelligence Course in Chennai
    PHP Training in Chennai
    Ethical Hacking Course in Chennai Blue Prism Training in Chennai
    UiPath Training in Chennai

    ReplyDelete
  49. This was not just great in fact this was really perfect your talent in writing was great. ExcelR Data Scientist Course In Pune

    ReplyDelete
  50. This is very interesting content! I have thoroughly enjoyed reading your points.Data Science Course in Hyderabad

    ReplyDelete
  51. Very nice post here and thanks for it .I always like and such a super contents of these post. oracle training in chennai

    ReplyDelete
  52. Thanks for the informative article. This is one of the best resources I have found in quite some time. Nicely written and great info.
    acte reviews

    acte velachery reviews

    acte tambaram reviews

    acte anna nagar reviews

    acte porur reviews

    acte omr reviews

    acte chennai reviews

    acte student reviews

    ReplyDelete
  53. I really appreciate the kind of topics you post here. Thanks for sharing us a great information that is actually helpful. Project Power Red Jacket

    ReplyDelete
  54. Very helpful blog post, explained everything very clearly, This blog really has all the info I was looking for. Thanks you for sharing. Electronics

    ReplyDelete
  55. Truly an amazing site. It helped me a lot to pursue knowledge about data science.Definitely recommending it to my friends. To know more about Online Data Science Course

    ReplyDelete
  56. Nice & Informative Blog !
    If you are looking for the best accounting software that can help you manage your business operations. call us at QuickBooks Customer Support Number 1-855-974-6537.

    ReplyDelete
  57. Nice Blog !
    Here We are Specialist in Manufacturing of Movies, Gaming, Casual, Faux Leather Jackets, Coats And Vests See Biker Boyz Jacket

    ReplyDelete
  58. Incredible blog here! It's mind boggling posting with the checked and genuinely accommodating data. Usmle Step 1 2020

    ReplyDelete
  59. Nice & Informative Blog !
    In case you are searching for the best technical services for QuickBooks, call us at QuickBooks Error 8007 and get impeccable technical services for QuickBooks. We make use of the best knowledge for solving your QuickBooks issues.

    ReplyDelete
  60. The most unique and creative TIC tee I have seen in a while. My Boxer has been wearing them ever since he was a pup and now is older and ready to take on the competition with a T-shirt that says: Most Unique Tecnic I Learn. It makes
    Buy pinterest accountsme laugh when I see his run-up to the dog crate and out there with his shirt off. He usually does this about three times, then goes back into his crate to snooze for about five or six hours before going to sleep. If you have a dog who loves to exercise and is always ready to play, then this tee would be a good choice for him. Buy Instagram accounts

    ReplyDelete
  61. The question is, why would anyone want to put up a nice blog in the first place? Is it just to impress people or do they haveBuy tinder accounts some kind of business behind the nice blog? Well, I believe you should take a look at how these two factors play into your decision on whether or not to set up a nice blog. The more you know before you get started the better chance you have at success with your new site.Buy yahoo accounts

    ReplyDelete
  62. Really good article. Keep sharing amazing content. If you want best research paper writing service then do follow the link for best writing service available online.

    ReplyDelete
  63. Infycle Technologies, the topmost software training institute in Chennai offers Oracle PLSQL training in Chennai for freshers and students, and Tech Professionals of any field. Other demanding courses such as Java, Hadoop, Selenium, Big Data, Android, and iOS Development, Digital Marketing will also be trained with complete hands-on training. After the completion of training, the students will be sent for placement interviews in the core MNC's. Dial 7504633633 to get more info and a free demo.Best Oracle PLSQL Training in Chennai | Infycle Technologies

    ReplyDelete
  64. I was very impressed by this post, this site has always been pleasant news Thank you very much for such an interesting post, and I meet them more often then I visited this site.Selena Astros Jacket

    ReplyDelete
  65. I am visiting first here. Really an awesome content and informative blog. Keep up this good work.
    Data Science Course Training in Hyderabad

    ReplyDelete
  66. Edius Pro 9.3 Free Download This Setup is Windows. It is Full Offline Installer. & Full Working. The installation process is very simple and you Edius 9 Free Download Full Version with Crack

    ReplyDelete
  67. Pubg PC Download free for windows pc Full version zip file, PUBG For PC download with torrent file crack for free with activation keys.Pubg Pc License Key Free

    ReplyDelete