We’ve been playing with Google Cloud Endpoints ever since the Trusted Tester program was announced at Google I/O 2012. We used it on several small/medium projects and had mixed experiences. Many of them good, but as with any bleeding edge technology, you can expect bugs and breaking changes. In this post, I will try to share our experiences with Google Cloud Endpoints and Google App Engine in general.
You might remember on Google I/O 2012, a lot of attention was given to the shiny new feature of App Engine called Google Cloud Endpoints. Meanwhile, Google announced new public APIs for a whole bunch of their products. How are these two related, you might ask? In the last couple of years, Google has invested heavily into building the new API infrastructure for their APIs. The goal was to tackle generic problems of Google engineering teams like scalability, authorization, discovery, caching, client libraries, billing, quotas and the like, thus keeping their focus on the logic of their services.
Great, what does that have to do with the rest of us? For starters, it gives us access to consistent set of Google APIs. Other than that, API discovery enables us to explore all public Google APIs. As a result of API discovery they have the ability to automatically generate multi-platform client libraries.
Google Cloud Endpoints is an experimental feature of Google App Engine that lets us leverage the power of Google API infrastructure in our App Engine apps. That’s pretty cool if you ask me 🙂
Before registering for the Trusted Tester program, we had very little experience with Google App Engine. We had experience developing RESTful back ends for mobile clients, but technologies we used were Spring and Grails. Naturally, the switch to the cloud wouldn’t come that easy. Using new technologies in production environment introduces risk. We wanted to test App Engine/Cloud Endpoints before actually using it on something big. Luckily, a fellow Calyx engineer, Ivan Gavran, had an idea for a simple Android app we could implement with minimal effort and no pressure because we would distribute it for free on the Play Store. Here’s the end product: https://play.google.com/store/apps/details?id=hr.calyx.android.pazimurja&hl=en
After managing to implement this simple app, we decided to use Google Cloud Endpoints on the next in-house project Hungr.io. This was a more serious project, so we had to evaluate the risks of using this technology more carefully.
Risks of moving to the Cloud
Choosing the platform for Hungr.io wasn’t easy. We had 3 options: Spring, Grails and the Google App Engine. The choice would affect not just the mobile (REST) back end, but the Web front end as well.
In the past, we (not me :)) worked a lot with Spring/GWT. This was our safest choice.
Lately, Grails has been our first choice for rapid development of REST services and simple CRUD apps. We used it on a few projects and we pretty much knew what to expect from it. Power of Spring, convention over configuration, lots of plugins, scaffolding for views and even controllers! URI mapping configuration in Grails along with integrated Jackson JSON serialization made it a good fit for REST service implementation.
And finally, Google App Engine. From the start, we knew choosing App Engine would introduce risk. We barely knew the environment, we had no server side MVC for the Web front end, and integrating heavy frameworks like Spring and GWT is discouraged on App Engine. On the other hand, we had Google Cloud Endpoints. In this scenario, the most elegant solution would be for Cloud Endpoints to be the only entry point to the server side. This means we would be forced to build an AJAX client for Web front end.
After much deliberation, we decided to go with Google App Engine and Cloud Endpoints. Risky, but with great prospect. Also, bleeding edge equals cool 🙂
App Engine environment is quite different from what we were used to. The main problem was the Datastore. We were burdened by experience. When we saw App Engine came with support for JDO and JPA, in interest of minimizing risk, we made use of JPA because we have worked with it in the past in our Spring based projects. In retrospective, we shouldn’t have. The Datastore is a NoSQL schemaless and scalable object datastore which is, in my opinion, crippled by JDO/JPA. The support for JDO/JPA was introduced to simplify potential migration between database vendors. As you probably know, JDO/JPA was designed for relational databases. Forcing it on a NoSQL datastore such as this results in incomplete API implementation and reduced flexibility of the original API.
After getting burned by JPA implementation limitations (no joins, no polymoprhic queries, no owned many-to-many relationships), we decided to use an alternate Datastore API. Besides JDO/JPA, App Engine SDK comes with the low-level datastore API that resembles Java Map interface. This is not very practical for regular use. We needed some domain restrictions/rules. We went with a very popular third party solution Objectify.What you get with Objectify is a simple and logical higher-level API to the Datastore. The main issue with this library is that it’s not maintained by Google, and that the currently recommended version is still in beta.
Along with the Datastore, you get a whole bunch of other useful services on App Engine. We use the BlobStore in combination with ImagesService for fast and cheap image hosting. ImagesService also includes support for free of charge image operations which comes in handy for thumbnail generation. Other services we made use of are the Channel API, naturally the Cloud Endpoints and UserService (implicitly using Cloud Endpoints). There are many more services out there.
Ok, enough about App Engine in general. How do you use Google Cloud Endpoints? Is it easy to use? What are the benefits? Are there any drawbacks?
There’s a great overview and documentation for Endpoints on Google Developers Web site: https://developers.google.com/appengine/docs/java/endpoints/
Using Google Cloud Endpoints is very straight forward. All that’s needed is to annotate the code you want to use as entry point to your app. After that, you can use the tools to generate client libraries and deploy your APIs. That’s all there is to it. The annotations contain the configuration for your APIs. You can manage the names of your endpoints/methods, versions, OAuth2 configurations, REST path and HTTP method mappings and more. You can also map path and query parameters. You don’t have to worry about JSON serialization/deserialization. It’s all done under the hood for you. If you follow REST conventions, you’ll have no issues. If you have an error in your annotations, there’s no tool that will warn you about it. You won’t know there’s a problem until you try to generate client libraries or you try to access the endpoint. Also, if client library generator fails, don’t expect any pretty error message. You’ll have to dig into eclipse error logs to find out what exception was thrown during generation.
- In your handler function, load your endpoint client with desired version. Supply a handler function for when the client is loaded
- In the second handler, do your stuff
The alternative is to make direct AJAX calls to the REST API. This is cool if you’re hosting your Web client on the appspot domain. If not, you might still be ok because your endpoints have support for CORS (Cross Origin Resource Sharing), but you can expect issues in some versions of IE and Opera (even the recent ones). Using the client library solves these issues using voodoo magic techniques I dare not speak of.
API Explorer is another cool tool you can use with your endpoints. It is used for API discovery and testing. You can explore Google APIs as well as the ones you have deployed using Cloud Endpoints. You can even make authorized requests! Not only that, but it also works on your local deploys! All you have to do to use this is to append /explorer to your endpoints root url. That’s all there is to it! Pretty cool and useful.
If you’re building a REST/RPC Web service for your mobile/Web front ends, don’t mind the common problems of bleeding edge technologies and you like the idea of deploying to the cloud, you should definitely check out Google Cloud Endpoints.
Learning the App Engine environment is straightforward. The biggest time consumer in our experience was the Datastore. If someone’s looking to build their own App Engine app, I would suggest they learned about the benefits of the Datastore. Don’t limit its potential with JDO/JPA thinking you don’t have time to learn something new. You’ll probably end up wasting much more time trying to understand why you can’t do something in JDO/JPA that you normally could. I would also highly recommend Objectify. If you’re unsure about limiting your self to App Engine and want to have the option of moving elsewhere, I don’t think you’ll profit much from JDO/JPA support that comes with App Engine. If you have simple enough data model that mentioned implementation limitations don’t bother you, you’ll probably have no problem moving from any other datastore API as well.