Google Cloud Endpoints Tutorial – Part 4

Welcome to Part 4 of the Google Cloud Endpoints Tutorial.

The full series:

  • Part 1 : We looked at writing a Google Cloud Endpoints class manually by using the various annotations and Exception classes that are available. We create a Quotes API that provided a JSON + REST based interface to manage Quotes (add, modify, delete and retrieve quotes).
  • Part 2 : We generated the Google Cloud Endpoints class from a JDO Annotated Entity class by using the Code Generation tools provided in the library.
  • Part 3 : Generated the Cloud Endpoints Client Library for Android and wrote an Android application that invokes the Endpoints API.
  • Part 4: We wrote a JavaScript client for our Endpoints API.
  • Part 5: Securing our API
  • Part 6: Calling a Secured API from a JavaScript client.
  • Part 7 : Calling a Secured API from an Android client.


This series covers Google Endpoints with Eclipse.

If you are looking for using Google Cloud Endpoints with Android Studio, I recommend my series on Gradle, especially the following parts:

  • Part 8 : Gradle + App Engine + Cloud Endpoints + Android Studio
  • Part 9 : Gradle + App Engine + Cloud Endpoints (Persistence) + Android Studio
  • Part 10 : Consuming Endpoints in your Android application


I have also published a list of Cloud Endpoints Tips:

  1. Check Endpoint Deployment Status
  2. Throw the Right Exception Classes
  3. Understand Injected Types
  4. Understand @API and @APIMethod Annotations
  5. Using Cursor and Limit parameters
  6. The @APIResourceProperty Annotation

In this episode

We are going to look at another client in this episode. This time, it will be a JavaScript client that we can use via the Google Java Script Client API that can interact with our Quotes Endpoint API.

What do you need ?

  • You have a working development environment for Google App Engine. This includes the Google Eclipse plugin.
  • The API Project 2 (Quotes Endpoint Project) loaded in your Development Environment. Even if you do not want to load it, just follow along in the tutorial to see how to invoke the API in your HTML page via Java Script.

My Development Environment

This remains the same, no changes at all. My development environment is given below:

  • Eclipse Juno
  • Google Eclipse plugin with App Engine SDK 1.8.8. This environment is needed just that I can run the Endpoints API locally and test the Java Script client against it.
  • Mac + Windows machine (I kept switching from one to another, to keep everyone happy ;-))

Revisiting the Quotes API

Let us recap quickly on what we have done so far. We have written a Quotes API hosted on Google App Engine that allows us to perform CRUD operations via a HTTP REST API. A Quote record contains a couple of attributes, the author and the famous quote that the author gave.

If you look at the API Methods, we had the following methods exposed:

Screen Shot 2014-01-12 at 4.21.42 PM

I will simply be writing the Java Script client in this episode and making sure that the App Engine project is up and running on my local machine.

Java Script Code in Action

Let us look at our HTML page in which we will invoke the Quotes Endpoint API via Java Script.

In a previous version of this post, I had demonstrated only the list Quotes method. Thanks to +Gerwin Sturm, who pointed out that there could be complications related to invoking the other REST methods (insert Quote, update Quote)  via the Google Javascript API client, I wanted to provide the code for all the operations.

So, we will be writing a test html page (apitest.html) that will provide functionality for all

  • Listing Quotes
  • Adding a New Quote
  • Updating a Quote
  • Deleting a Quote.

I have a few quotes present in the Datastore and the apitest.html page is shown below. I have retrieved all the Quotes when the List Quotes button is clicked, as shown below. I have 3 Quotes in my datastore currently and I am displaying the quote text, author and in square brackets at the end, I have the ID , which is provided here to make it a bit easier for us to perform operations for updating and deleting the quote, which will require an ID.

Screen Shot 2014-01-24 at 11.55.08 AM

The page listed above should be straightforward to understand. It has various sections to perform the different operations.

Client code

The full source listing for apitest.html is given below. Let us cover the important points:

  • The Quotes Endpoints API is available as a HTTP REST API and you can definitely use standard Ajax Java Script code to invoke the API to do the same.
  • To speed up things, Google has provided a Javascript API that is an easier way to access all the Google APIs and Google Cloud Endpoints is no exception. You should definitely check out the API reference.
  • The first thing we are going to do is load the Javascript API via the <script> tag that you will find at the end of the code listing.<script src=””></script&gt;
  • Once the file is loaded, we pass our init function that can be invoked.
  • The init method does an important thing. It invokes the gapi.client.load method that loads the client library interface to a particular API. The particular API in question is our Quotes API.
  • The method parameters for the gapi.client.load method is shown below (Refer to the docs too!)
    • name : This is the name of the API. In our case it is quoteendpoint. If you look at the Endpoint API source code, you will notice that the @API(name…) is equal to quoteendpoint.
    • version : This is the version of the API. It is v1 in our case.
    • callback : This is the function to be called once the API Interface is loaded.
    • API Root : This is the API Root URL i.e. protocol://hostname:port/_ah/api. Since we are running and testing it against the local host, it is http://localhost:8888/_ah/api
  • After the gapi.client.load method, you will find that we have created standard event handlers for all the 4 buttons that invoke the respective functions i.e. listQuotes(), insertQuote(), updateQuote() and deleteQuote().
  • The Google Client API is invoked in a standard fashion. In the listQuotes() method, you will notice that we are invoking gapi.client.quoteendpoint.listQuote().execute(…) method. One of the ways to figure out the different methods is also to use the Chrome Dev tools as shown below:
    Screen Shot 2014-01-18 at 6.52.42 PM
  • The callback method inside of the execute method, returns back the JSON result as we have seen before:
    Screen Shot 2014-01-18 at 6.51.45 PM
  • We simply iterate through the items and populate the div element with the results. In particular, we use the author and message attributes of each item.
  • For the insertQuote() method, we first retrieve the 2 attributes i.e. Author Name and Quote Text. One can do validations like empty values are not allowed, but we can leave that as an exercise for the reader. We create the Request Object for the insertQuote() method , which should look something like the following:
    { “author”:”…”, “message”: “…”} and then we simply invoke the gapi.client.quoteendpoint.insertQuote(<RequestObject>).execute(…) method
  • For the updateQuote(), we first retrieve the 3 attributes i.e. ID, Author Name and Quote Text.  We create the Request Object for the updateQuote() method , which should look something like the following:{ “id”: “…”, author”:”…”, “message”: “…”} and then we simply invoke the gapi.client.quoteendpoint.updateQuote(<RequestObject>).execute(…) method
  • For the deleteQuote(), we only need the ID We create the Request Object for the deleteQuote() method , which should look something like the following:{ “id”: “…”} and then we simply invoke the gapi.client.quoteendpoint.updateQuote(<RequestObject>).execute(…) method


  • You should play with the API explorer more for all the operations, so that you are aware of what HTTP Responses are being received for each of the operations. For e.g. in the case of a successful delete a 204 No Content is returned and so on. Understanding this will help you create the right kind of client messages that you can display to the user.
  • You should definitely visit the Cloud Endpoints generated code for your API. What I mean is that you will need to most likely modify the Datastore API code to make your API more robust and provide the correct HTTP Exceptions. As an example, before you attempt to delete a Quote, you might want to check for its existence. And if it does not exist, you might want to throw a 404. So look at your API from that angle to make it more solid.

Project Source Code

I have updated the source code for the MyAPIProject2, which is the same source as the one that we saw in Part 2, except that an additional file apitest.html has been added. You can download the entire source code over here.

Hope you liked this episode of the Google Cloud Endpoints tutorial.  Check out the next episode on how to secure your API.


18 thoughts on “Google Cloud Endpoints Tutorial – Part 4

  1. Hi Romin,

    Thanks for the wonderful tutorial ,and the demo at the Google Cloud Roadshow Bangalore 🙂

    I am using Eclipse 4.3 and Google App Engine SDK 1.9.6.
    Whenever I try to Invoke “Generate cloud Endpoint Client Library” … I get this error…

    at org.eclipse.jface.operation.ModalContext$
    Caused by: java.lang.ClassNotFoundException:$Language

    Funny thing is, when I Right click my POJO and generate the Endpoint Class, it automatically generates the Endpoint API, but not when I explicitly do it …

    Any hints ? I’m on Ubuntu 14.04 with Java 1.7 (Oracle).

    1. Thanks for the feedback. Much appreciated.

      The problem that you are describing has been noticed several times by people when using some combination of App Engine SDK + Eclipse. Unfortunately, I am not in the position to pin point which precise version you should use. But I suggest the following, try to downscale your App Engine SDK to say 1.9.3 or 1.9.4 and see if the problem is resolved. Several folks have reported this.!topic/google-appengine-stackoverflow/82mObuf7_Uw

  2. Hi Romin,
    Thanks for the informative and helpful tutorial!
    I was wondering if I need to load gapi (meaning ) on every page that i want to use the api functions?
    I have an api call that returns a data of an image and on my js i display the image when receiving the data. it takes a long time to load the gapi so the performance of this page is poor.
    is there a way to enhance it?

    1. I don’t think there is a need to load them on every page. If you are using JavaScript frameworks like AngularJS for example, you can load these as service/singleton and then use them in the rest of your application.

  3. Thanks so much for these great tutorials. I haven’t been able to find this info anywhere else, and the code examples you’ve provided are extremely helpful. Huge thanks!

  4. i Romin,

    Thanks for the amazing tutorial.

    Only one question : Why i cant see my Entity on DataStore Console en the google Cloud.?

  5. Hello, this is a great guide and was exactly what i was looking for to avoid using angularjs. I have one question though.

    I am getting an error that gives me a GET 404 error and i am unable to run the page.

    I am not sure what the callback function should be and i am not 100% sure that my API root is correct ‘’

    Any advice on this??

    1. Sam – Thanks for the feedback. Here is what I would like to confirm first:
      1) Have you deployed the App Engine application under ‘exampleapp’ application ID or is it some other id?
      2) After deploying, are you able to access the API Explorer successfully via the _ah/api/explorer endpoint? Does the API function correctly as you expect?

  6. Romini, Thank you for the wonderful tutorial. I was able to run the tutorial… How do I debug the code in the execute function? for example in the chrome developer tool, I have setup a breakpoint in the result=results+… statement, however the debugger never stops at the breakpoint. interestingly it will execute the code.

    Am I missing anything?

    gapi.client.quoteendpoint.listQuote().execute(function(resp) {

    if (!resp.code) {

    resp.items = resp.items || [];

    var result = “”;

    for (var i=0;i<resp.items.length;i++) {

    result = result+ resp.items[i].message + "…" + "” + resp.items[i].author + “” + “[” + resp.items[i].id + “]” + “”;


    document.getElementById(‘listQuotesResult’).innerHTML = result;



  7. Nice tutorial on understanding endpoints. you mentioned “The Quotes Endpoints API is available as a HTTP REST API and you can definitely use standard Ajax Java Script code to invoke the API to do the same.”

    For a simple fetch of an user by id using standard ajax call

    function selectUser(id) {

    type : ‘GET’,
    url : ‘/rest/users?id=’ + id,
    contentType : “application/json; charset=utf-8”,
    datatype : ‘json’,
    success : more code


    Here what is the URL for your quotes example ???

    Note: I am not using google custom javascript api.

    My invocation is from an adobe air mobile application. (actionscript 3)

    something like

    //Create the HTTP request object
    var request = new air.URLRequest( “” );
    request.method = air.URLRequestMethod.GET;

    What would be the destination url for List quotes or Insert New quote.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s