Tuesday, September 3, 2013

Google Cloud EndPoints - GAE Server Configuration v1


Goals:

  • Create a service in Google App engine (GAE) to serve different external clients (WEB and Android) placing the Model and Controller in one single point (GAE) making simpler the integration from different Views (WEB, Android and iOS).
  • Use Google Cloud EndPoints (JAVA) for the communication between Server and Clients.
  • v1 with open connection without authentication (OAuth).
  • Study Case: Simple app to create notes.


Environment:

Idea:

  • Google Cloud EndPoints: Placing all the business logic (Model and Controller) in one single server (GAE) makes easier and simpler the development of the different clients (Views) that can access to it. 
  • These EndPoints wrap the logic needed to access to a remote service in a simple API. It is not necessary to manage the communication via HTTP calls, like opening and closing the connection, configuring the end point to access, creating the query string, etc.
  • Cloud EndPoints will create and provide the API, access specifications and infrastructure to access a GAE from clients like WEBAPP, Android or iOS.  


Testing App:

  • Note entity with:
    • Id
    • Email Address
    • Description
  • Server on Google Appengine.
  • Clients:
    • WEBAPP.
    • Android.

Development Steps:

  • Back-End Server creation:

  • Using GPE we create a "New Web Application Project":



  • GPE creates a project with the following structure by default:



  • As we are not using Servlets in this project we can remove all classes and configuration related to it:
    • Java class "CloudEndPoints_Server_GAP_v1Servlet.java"
    • web.xml configuration:

      <servlet>  
           <servlet-name>CloudEndPoints_Client_HTML_v1</servlet-name>  
           <servlet-class>com.dtorralbo.CloudEndPoints_Client_HTML_v1Servlet</servlet-class>  
      </servlet>  
      <servlet-mapping>  
           <servlet-name>CloudEndPoints_Client_HTML_v1</servlet-name>  
           <url-pattern>/cloudendpoints_client_html_v1</url-pattern>  
      </servlet-mapping>  


  • POJO Model creation:

  • Create a POJO that represents the entity we will use (Note).
  • The Model interface we will use is JDO.
  • We will place this entity in the "com.dtorralbo.db" package.




  • We annotate the POJO attributes as corresponds.



  • EndPoints Generation:

  • GPE will help us to generate the EndPoints from the POJO created, so that we will be able to manage this data structure from any client.

  • We execute "Google > Generate Cloud Endpoint Class" over each POJO in our project:


  • During this process, GPE generates 3 new files:
    • PMF.java: Factory in charge of providing object type "PersistenceManagerFactory" that will be used to store and retrieve from DB the POJOs we are working with.
    • NoteEndpoint.java: Endpoint with the Model logic to manage the Note objects, like:
      • List entities: CollectionResponse<Note> listNote(String, Integer)
      • Get an entity from its id: Note getNote(String id)
      • Add a new entity: Note insertNote(Note note)
      • Update a already present entity: Note updateNote(Note note)
      • Remove: Note removeNote(String id)
    • noteendpoint-v1.api: in the path "/war/WEB-INF/", it is the descriptor of the API generated in JSON format. It is used in the API console (<your-service>.appspot.com/_ah/api/explorer) to show all the description and info that this API has.

  • Refactoring of the generated code:
    • Refactor of the package names for a more proper classification:



    • API annotation modification for a more legible nomenclature:
      • API configuration: name, version, etc.

      @API(
            name = "noteendpoint",
            version = "v1"
      )


  • Services configuration:


      @ApiMethod(name = "note.list")
      @ApiMethod(name = "note.get")
      @ApiMethod(name = "note.insert")
      @ApiMethod(name = "note.update")
      @ApiMethod(name = "note.remove")


  • GPE generates automatically the basic services to manage the entities in the DB. But Google Cloud EndPoints allows you to add any further custom service that your API may require.


  • These basic services are indeed RESTful services that can be reached with the following HTTP methods:
    • listNote > GET
    • getNote > GET
    • insertNote > POST
    • updateNote > PUT
    • removeNote > DELETE


  • Once we created the Endpoints, we will create the clients API. These are the libraries that will be used by the clients to reach and work with our new API and its services. Over the project, we execute "Google > Generate Cloud Endpoints Client Library"



  • This process will generate a set of new files and directories used by the clients that will access to the services:
    • noteendpoint-v1-rest.discovery y noteendpoint-v1-rpc.discovery: In the path "/war/WEB-INF/". Descriptors with value information of the API services for REST and RPC access. Basically they contain util information in case we prefer to access to the service via REST or RPC interfaces, offering info like name of the available services, parameters needed by each service, etc.
    • endpoint-libs: This new directory will contain all the code useful for the clients.


  • The library in this case called "myapp_appspot_com-noteendpoint-v1-20130902175821-java-1.15.0-rc-sources.jar" is the client library that in our example the Android app will use to access to our API. With this library, the Android developer won't need to care nor manage the communication issues to an external service.

  • This library contains exactly what we can find in the path "/endpoint-libs/libnoteendpoint-v1/noteendpoint/noteendpoint-v1-generated-source/". So that we can check o review the code we will provide to the clients without unzipping the jar file.



      davidtorralbo$ jar -tvf myapp_appspot_com-noteendpoint-v1-20130902175821-java-1.15.0-rc-sources.jar 
           0 Tue Jan 01 00:00:00 EST 1980 com/
           0 Tue Jan 01 00:00:00 EST 1980 com/appspot/
           0 Tue Jan 01 00:00:00 EST 1980 com/appspot/myapp/
           0 Tue Jan 01 00:00:00 EST 1980 com/appspot/myapp/noteendpoint/
        6557 Tue Jan 01 00:00:00 EST 1980 com/appspot/myapp/noteendpoint/NoteendpointRequest.java
       26054 Tue Jan 01 00:00:00 EST 1980 com/appspot/myapp/noteendpoint/Noteendpoint.java
           0 Tue Jan 01 00:00:00 EST 1980 com/appspot/myapp/noteendpoint/model/
        2747 Tue Jan 01 00:00:00 EST 1980 com/appspot/myapp/noteendpoint/model/CollectionResponseNote.java
        2754 Tue Jan 01 00:00:00 EST 1980 com/appspot/myapp/noteendpoint/model/Note.java
        3549 Tue Jan 01 00:00:00 EST 1980 com/appspot/myapp/noteendpoint/NoteendpointRequestInitializer.java
        2658 Tue Jan 01 00:00:00 EST 1980 pom.xml



  • Testing the endpoints in local:

  • We can test our new endpoints before deploying them to GAE.
  • To do that, we firstly launch the GAE server in local as a "Web application"

  • There are several ways to test our endpoints in local:
    • RESTful access:

      davidtorralbo$ curl --header "Content-Type: application/json" -X GET http://localhost:8888/_ah/api/noteendpoint/v1/note/id1      
      {
        "id" : "id1",
        "emailAddress" : "davidtorralbo@gmail.com",
        "description" : "note #1"
      }









      davidtorralbo$ curl --header "Content-Type: application/json" -X POST -d '{"id":"id2", "emailAddress":"davidtorralbo@gmail.com", "description":"note #2"}' http://localhost:8888/_ah/api/noteendpoint/v1/note      
      {
        "id" : "id2",
        "emailAddress" : "davidtorralbo@gmail.com",
        "description" : "note #2"
      }







      davidtorralbo$ curl --header "Content-Type: application/json" -X GET http://localhost:8888/_ah/api/noteendpoint/v1/note      
      {
        "items" : [ {
          "id" : "id1",
          "emailAddress" : "davidtorralbo@gmail.com",
          "description" : "note #1"
        }, {
          "id" : "id2",
          "emailAddress" : "davidtorralbo@gmail.com",
          "description" : "note #2"
        } ]





      • If we click on our API (noteendpoint API), we will explorer all the services.
 

      • We can choose and test any of these services, e.g. "note.insert" for creating a new note.

      • Thanks to the descriptors we talked before, the API console can assist you to complete the parameters needed in each service.


      • Once we execute it, we can see in the API console both the RESTfull call done and the response we got from the service.

      • To complete the tests, we can check if the new Note was properly created in our local db. The GAE console (http://localhost:8888/_ah/admin) helps you to do that in the "Datastore Viewer" section.





  • Deploying to App Engine:
  • Create a new Application in Google App engine:

  • Configure our application id in the "appengine-web.xml" file:

      <appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
            <application>cloudendpointsservergae</application>
            <version>1</version>
            [...]


  • Deploy to App Engine:



Once we published our application we can test our services and the behavior is the expected one:

  • Create a new note with the API console:





  • List all the notes:



We have to take into account that once we place the application in Google App Engine we ill have to access to our EndPoints via SSL communications, using for that the HTTPS protocol.







No comments:

Post a Comment