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.

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=”https://apis.google.com/js/client.js?onload=init”></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

Observations

  • 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.

About these ads

About rominirani

Google Developer Expert Cloud 2014. Harnessing the power of software by learning, teaching and developing simple solutions. I love learning about new technologies and teaching it to others.
This entry was posted in Cloud Computing, Google App Engine and tagged . Bookmark the permalink.

11 Responses to Google Cloud Endpoints Tutorial – Part 4

  1. Pingback: Google Cloud Endpoints Tutorial – Part 1 | iRomin

  2. Pingback: Google Cloud Endpoints Tutorial – Part 3 | iRomin

  3. Pingback: Google Cloud Endpoints Tutorial – Part 5 | iRomin

  4. Pingback: Google Cloud Endpoints Tutorial – Part 6 | iRomin

  5. Pingback: Google Cloud Endpoints Tutorial – Part 7 | iRomin

  6. ccscoder says:

    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…

    java.lang.reflect.InvocationTargetException
    at com.google.gdt.eclipse.appengine.swarm.wizards.GenerateSwarmApiAction$1.run(GenerateSwarmApiAction.java:82)
    at org.eclipse.jface.operation.ModalContext$ModalContextThread.run(ModalContext.java:121)
    Caused by: java.lang.ClassNotFoundException: com.google.api.server.spi.tools.ClientLibGenerator$Language
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)

    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).

  7. Pingback: Google Cloud Endpoints Tutorial – Part 2 | iRomin

  8. Leah says:

    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?

    • rominirani says:

      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.

  9. Jason says:

    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!

Leave a Reply

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

WordPress.com Logo

You are commenting using your WordPress.com 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 )

Google+ photo

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

Connecting to %s