December 2017 : This tutorial has not been updated for a while now and there could be breaking changes. I suggest that you instead reference the official documentation at https://cloud.google.com/endpoints/docs/frameworks/java/about-cloud-endpoints-frameworks

Welcome to Part 2 of the Google Cloud Endpoints Tutorial.

The full series:

Part 1 : We look 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 provides a JSON + REST based interface to manage Quotes (add, modify, delete and retrieve quotes).

Part 2 : Generate the Google Cloud Endpoints class from a JDO Annotated Entity class by using the Code Generation tools provided in the library.

Part 3 : Generate the Cloud Endpoints Client Library for Android and an Android application that invokes the Endpoints API.

Part 4: Writing 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.

IMPORTANT

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:

In this episode

In this part of the series, the end goal for us is the same i.e. to generate the Quotes API. However, we shall let the Cloud Endpoints classes do the magic for us by helping us generate the API Endpoint class, instead of us writing it by hand.

What do you need ?

Basic understanding of Java Web Development, which includes Servlets, JSP, WAR file structure, etc.

You have a working development environment for Google App Engine. This includes the Google Eclipse plugin.

You do not need to be an expert at JDO or JPA. We shall be using some JDO annotations for our Entity class to allow it to declare itself as being available for persistence and what attributes of the class is a key and should be persisted. Just follow the tutorial along the way and you will be just fine.

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

Mac machine (but Windows will do too!)

Attention-> Cloud Endpoints became GA (General Availability) in Release 1.8.7 of the App Engine SDK. The latest release as of App Engine at the time of writing is 1.8.8.

Create App Engine Project

The first thing we will do here is to generate a new App Engine project. Let us not disturb anything that we did with the project from their previous part of this tutorial series.

Assuming that you are using Eclipse, do the following:

Select File -> New -> Project. Select Google and Web Application Project. Click on Next.

In the Project name, choose a suitable name. I have named my Project : MyAPIProject2. For the package name, I have provided com.mindstorm.famousquotes. Deselect the GWT option. Leave the other options as default. Click on Finish.

This will generate the App Engine project for you.

The Entity Class — Quote.java

The next thing we are going to do is write our Quote class. This class is similar to the one that we saw in the previous episode. I have stripped it down further by removing the hashcode/equals/etc methods from the class to keep our focus clear.

The Quote entity still has 3 main attributes : id, author and the message.

What you will find different here is that the class is JDO Enabled. Take a look at the full source code for the JDO enabled Quote entity class and we will discuss further.

Let us discuss the main points:

We mark our Quote class for Persistence via the @PersistenceCapable annotation. This is done right at the top of the class declaration.

annotation. This is done right at the top of the class declaration. Each attribute of the class that we would like to persist is marked with a @Persistent Annotation. If you do not want to persist any specific attribute mark it with @NonPersistent . But in our case, this does not arise.

Annotation. If you do not want to persist any specific attribute mark it with . But in our case, this does not arise. We need to specify which attribute is the Identifier Key i.e. which can be used to uniquely identify a specific record in the datastore. In our Quote class, the Id attribute will always have a unique value for each record, hence we give it an additional annotation @PrimaryKey .

. Notice that for the Id attribute, we have also provided an additional attribute for the @Persistent annotation. We have specified that a valueStrategy and the value of which says that the underlying JDO implementation will take care of providing it a unique ID. What this means is that when we want to persist a Quote object, we will simply have to construct the Quote object and populate its author and message attributes. The Id value will be filled up appropriately for us at the time of persistence.

Make sure that you have saved this class, before moving on to the next step.

Generating the Quote Endpoints class

Now that we have our Quote JDO Entity class in place, we are going to tell the Endpoints library to help generate the Endpoint API class, with the full JDO implementation such that we do not have to worry about writing the code that deals with the Datastore API, that App Engine provides.

Let us generate the API Endpoints class now. To do that, do the following:

Right-click on the Quote class in your Eclipse IDE and select Google -> Generate Cloud Endpoint Class as shown below:

This will generate a couple of Java classes for you in the same package that your Quote Java class is present in.

The 2 files generated are PMF.Java and QuoteEndpoint.java. The QuoteEndpoint.java is of particular importance to us and it contains the Endpoints class.

and The QuoteEndpoint.java is of particular importance to us and it contains the Endpoints class. Take a look at QuoteEndpoint.java. If you have followed Part 1 of the tutorial, you will notice that the method signatures if not the method implementations look familiar. They contain the usual methods for inserting, updating, deleting and fetching Quotes, almost similar looking to the ones that we wrote by hand.

At this point in time, you could actually just Build your project and Run the Web application and the API will be available to you if you navigate to the _ah/api/explorer endpoint in your local browser. You can try out the method for the QuoteEndpoint and not worry about what happens behind the scenes but you will only get so far, hence we will get into the details of what the code is doing and in fact, even correct a problem or two with the generated code.

Lets move on.

Dissecting the generated Quote Endpoints class

If you look at the QuoteEndpoint.java class that has got generated, you will find the following methods that it generated.

The Green circle indicates public methods, which means that the methods will be exposed by the API Endpoint. A couple of methods are private methods here and are used by the other methods.

The getPersistenceManager() private method is used to get an instance of the PersistenceManager implementation. The second Java file (PMF.java) that was generated for you, contains the details for getting the instance. This is standard boilerplate code for getting a handle to the Persistence Manager in the JDO/JPA world.

OK. Over to the API Endpoint methods now. These are all the public methods in the class. Just a side note that if you plan to enhance the functionality and need to write your own methods but do not want to expose them as API methods, do remember to mark them as private.

The entire source code for the QuoteEndpoint.java file is shown below. In fact I did modify the code slightly to make it work for me in the way that I wanted and I will discuss that in the next section (Modifying the Source Code):

The main points to note are:

Note the @API annotation used at the top to identify that this is an API class. The namespace stuff is used when we generate our client libraries and we will look at that in the next tutorial or two but for now, don’t worry too much — though you will be able to understand that it uses your package names from the project.

annotation used at the top to identify that this is an API class. The namespace stuff is used when we generate our client libraries and we will look at that in the next tutorial or two but for now, don’t worry too much — though you will be able to understand that it uses your package names from the project. Each of the methods should be understandable now to you based on our learning from the previous part. Each of the public methods that need to be present in the API are annotated with the @APIMethod annotation. A name attribute specifies the name of the method.

annotation. A name attribute specifies the name of the method. Pay attention to a new annotation used for parameters passed to the public API methods. The annotation is @Nullable and it means that it is not a mandatory parameter to be passed.

and it means that it is not a mandatory parameter to be passed. The method implementations are not difficult to understand. Each of the method implementations simply gets a handle to the persistence manager, then performs appropriate DB operations for get, update, insert , delete and then closes the persistence manager object, so that the operation can be committed by the Datastore implementation.

Important point :

The method signatures that you see here are generally regarded as Best Practices for a REST API. You can always debate for example, if you want to pass a Quote object to the insert method or you want to pass individual parameters i.e. author and message.

The point is that nothing stops you from following a style that suits you. So there is a lot of flexibility that is available here from an interface point of view. You decide if the method names need to be different, if you would like to use POST instead of GET, if you want individual parameters instead of the whole Quote object and so on. Just refer to the full Annotation documentation and understand them better.

Modifying the Source Code

Just to demonstrate that things are flexible and that you might not find the Google code at times, appropriate to your functionality — I modified the generated code a bit.

Refer to the insert method shown below. The parameter to be passed is the whole Quote object and while inserting a new record, remember that we had discussed that we will only pass the author and the message attributes. We will keep the Id field empty or not provide it since we would like the Id generation strategy to be automatically handled by the JDO implementation.

@ApiMethod(name = “insertQuote”)

public Quote insertQuote(Quote quote) {

PersistenceManager mgr = getPersistenceManager();

try {

if (quote.getId() != null) {

if (containsQuote(quote)) {

throw new EntityExistsException(“Object already exists”);

}

}

mgr.makePersistent(quote);

} finally { mgr.close(); }

return quote;

}

The original code did not have the check that I have added in bold and as a result, the API implementation was crashing if I provided a new Quote object to be added without providing the Id (which I did not want to provide in any case).

In the next section, you will observe that I do not pass the Id value when using the insertMethod.

Testing out the API

You can test out the API in the same fashion i.e. via the API Explorer, which is also available locally.

We will keep our testing limited to a call or two, since I am assuming that you are comfortable with it now.

To Test the API, do the following:

Run the Web application.

Assuming that it is running on port 8888 , go to http://localhost:8888/_ah/api/explorer . Make sure you are connected to the Internet.

, go to . Make sure you are connected to the Internet. Click on the Quote Endpoint and you will find a list of methods. Specifically, let us click on the insertQuote method.

method. This brings up the screen as shown below:

Notice that we are populating only the author and the message attributes. We are not providing the id, since we want that to be system generated and unique and the underlying JDO implementation handles that for us.

Click on the Execute button and it should insert the record successfully for you. The sample run from my system is shown below:

You can try out the other API methods if you want. They should work well.

Datastore Viewer

Since the code generated works with the Datastore, every successful INSERT of a Quote record will end up as a record inside the App Engine Datastore. You can validate this within your local development environment too.

Before you check the Datastore, make sure that:

You have started the Web application

Used the API Explorer http://localhost:8888/_ah/api/explorer and invoked the insertQuote method a few times and checked if the successful execution has happened.

and invoked the method a few times and checked if the successful execution has happened. Then visit http://localhost:8888/_ah/admin i.e. the normal Administration console URL in your browser. If you visit the Datastore link, you should see an entity Quote available and you could take a look at the different records. An example screenshot from my environment is shown below:

Some comments

Cloud Endpoints generates for us a Endpoint Java class. This should not be taken as the final class that we should not or cannot modify . You had learnt in the first part of the tutorial about the different annotations and method parameters. You are free to change any of the generated class code to suit your API style and requirements.

. You had learnt in the first part of the tutorial about the different annotations and method parameters. You are free to change any of the generated class code to suit your API style and requirements. The code that is currently generated for a JDO/JPA Entity class works with the App Engine Datastore service. So if you are not planning to use this infrastructure service in your application, then you will need to modify the Endpoint class accordingly.

The generated code is by no means production ready and you should build in your own validations and Exception classes as needed. For e.g. it is good practice to make sure that all the request parameters contain valid values before you go ahead with any of the operations. In the code that we modified, we simply put in an additional check to see if the ID is provided, etc. But I would even go further and make sure that valid values for Author and Message are provided. Only then would I go ahead and do any persistent operations , else I would just reject the call there itself with the appropriate Exception.

Download Full Source Code

I suggest that you begin with a full download of the project source code.

Go ahead & download the code from :

Hope you liked this episode. In the next part (Part 3) of this series, we shall see how to generate client libraries (particularly for Android) and consume it from our Android application.

Till then, have a good time generating Cloud Endpoints classes.