Overview

About this codelab

  • The entire codelab (excluding optional steps) should take about one hour
  • There are time estimates included with each numbered step, so you can pace yourself
  • There are also un-numbered introductory steps that should take 20 minutes or less
  • If you get stuck, checkpoint .zip files are included periodically — just download one and pick up where it leaves off (but make sure to reset any configuration parameters to what you set for your own application)
  • http://goo.gl/GPM8L

Why we're here

  • App Engine makes a great backend for mobile applications:
    • Easy to get started
    • Easy to scale
    • Easy to maintain
    • Easy to manage
    • Pay for what you use

Introducing Google Cloud Endpoints

  • Easy to create a scalable API, hosted on App Engine, leveraging Google's API infrastructure
  • Shares many of the same tools and features that make Google's own APIs easy to use:
    • Automatic discovery powering the APIs Explorer and dynamic client libraries (e.g. JS)
    • Statically-typed client libraries in Java and Objective-C
    • Built-in support for OAuth 2
    • Runs at Google scale

Stop talking and show me a demo!

Demo

- - -
- - -
- - -

Recent Games

    That's cool! Are we going to build that?

    In this codelab we're going to:

    • Extend this API to store and retrieve scores using Google App Engine
    • Call the new API methods from JavaScript
    • Generate an Android client library

    But first, some prerequisites

    Architecture of Tic Tac Toe

    Architecture of Tic Tac Toe

    Architecture diagram

    Let's start building

    Step 1: import the starter project

    10 minutes

    • Download and unzip this Google App Engine starter project
    • From the command line, run /path/to/pre-release-sdk/dev_appserver.py /path/to/tictactoe-codelab
    • Verify the application is running by visiting http://localhost:8080/hello
    • Return to the command line and stop the application

    Step 2: configure the starter project

    10 minutes

    • Go to appengine.google.com and create a new application
    • Enroll your application in the codelab with the following form
    • In your editor of choice, open the app.yaml file for editing
    • Replace application: tictactoe-codelab with application: your-app-id
    • From the command line, deploy your application via
      /path/to/pre-release-sdk/appcfg.py --oauth2 update /path/to/tictactoe-codelab
    • Enter your Google account credentials if prompted
    • Confirm your application is running by visiting http://your-app-id.appspot.com/hello

    Step 3: add methods to existing Cloud Endpoint

    20 minutes

    API and method decorators tell the SDK how our classes should respond to API requests:

    • The @endpoints.api decorator indicates the class is an API
    • The @endpoints.method decorator indicates the method is an API method
    • Both of these allow you to specify some metadata about each method and API, such as the name of the API or the path (such as /mymethod) of the API call

    In addition, ProtoRPC message classes give a way to represent requests and responses as Python objects

    • Indicate to Google's API infrastructure the structure of request and response payloads

    Check out an example on the next slide...

    Step 3: add methods to existing Cloud Endpoint

    20 minutes

    import endpoints
    from protorpc import messages, remote
    
    class BoardMessage(messages.Message):
      state = messages.StringField(1, required=True)
    
    @endpoints.api(name='tictactoe', version='v1', description='Tic Tac Toe API')
    class TicTacToeApi(remote.Service):
      @endpoints.method(BoardMessage, BoardMessage,
                        path='board', http_method='POST',
                        name='board.getmove')
      def BoardGetMove(self, request):
        ...
        return BoardMessage(state=...)

    Step 3: add methods to existing Cloud Endpoint

    20 minutes

    For this step, look for the TODOs in tictactoe_api.py, tictactoe_api_messages.py and app.yaml:

    • Define ScoreIdMessage in tictactoe_api_messages.py
    • Add request and response message classes to the @endpoints.method decorator on ScoresInsert
    • Add the @endpoints.api decorator to ScoresList
    • Update app.yaml with the needed handler for serving API requests

    See Step 4 for testing instructions

    Do all the TODOs

    Step 3: add methods to existing Cloud Endpoint

    20 minutes

    class ScoreIdMessage(messages.Message):
      id = messages.IntegerField(1, required=True)
    
    @endpoints.api(name='tictactoe', version='v1', description='Tic Tac Toe API')
    class TicTacToeApi(remote.Service):
      ...
      @endpoints.method(ScoreIdMessage, ScoreResponseMessage,
                        path='scores/{id}', http_method='GET',
                        name='scores.get')
      def ScoresGet(self, request):
        entity = Score.get_by_id(request.id)
        if entity is None:
          raise endpoints.NotFoundException('Score not found.')
        return entity.ToMessage()
      # continued on next slide ... 

    Step 3: add methods to existing Cloud Endpoint

    20 minutes

    @endpoints.api(name='tictactoe', version='v1', description='Tic Tac Toe API')
    class TicTacToeApi(remote.Service):
      # continued from previous slide ...
      @endpoints.method(ScoreRequestMessage, ScoreResponseMessage,
                        path='scores', http_method='POST',
                        name='scores.insert')
      def ScoresInsert(self, request):
        entity = Score(outcome=request.outcome)
        entity.put()
        return entity.ToMessage()
      # ... 

    Step 3: add methods to existing Cloud Endpoint

    20 minutes

    @endpoints.api(name='tictactoe', version='v1', description='Tic Tac Toe API')
    class TicTacToeApi(remote.Service):
      # ...
      @endpoints.method(ScoreListRequest, ScoreListResponse,
                           path='scores', http_method='GET', name='scores.list')
      def ScoresList(self, request):
        query = Score.query()
        if request.order == ScoreListRequest.Order.TEXT:
          query = query.order(Score.outcome)
        elif request.order == ScoreListRequest.Order.WHEN:
          query = query.order(-Score.played)
        items = [entity.ToMessage() for entity in query.fetch(request.limit)]
        return ScoreListResponse(items=items)

    Step 3: add methods to existing Cloud Endpoint

    Solution

    Stuck? Download this file which contains the steps we just completed

    • Replace application: tictactoe-codelab with application: your-app-id

    Step 4: test locally and in production

    10 minutes

    Step 5: try the API with JavaScript

    10 minutes

            <body>
              <script type="text/javascript">
                function init() {
                      gapi.client.load("tictactoe", "v1", function() {}, "/_ah/api");
                }
              </script>
              <script src="https://apis.google.com/js/client.js?onload=init"></script>
            </body>
            gapi.client.tictactoe.scores.insert({"outcome": "WIN"}).execute(function(resp) {
                console.log(resp);
            });
            gapi.client.tictactoe.scores.list().execute(function(resp) {
                console.log(resp.items[0]);
            });

    Step 6: generate Mobile client libraries

    10 minutes

    • Edit tictactoe_api.py to specify the hostname of your API:

      @endpoints.api(name='tictactoe', version='v1', description='Tic Tac Toe API',
                     hostname='your-app-id.appspot.com')
      class TicTacToeApi(remote.Service):
      ...
      

    • Generate the library:

      /path/to/pre-release-sdk/endpointscfg.py get_client_lib java -o . -f rest tictactoe_api.TicTacToeApi

    Step 6: generate Mobile client libraries

    10 minutes

    How to call the client library from Android:

              HttpTransport transport = AndroidHttp.newCompatibleTransport();
              JsonFactory jsonFactory = new GsonFactory();
              Tictactoe service = new Tictactoe(transport, jsonFactory, null);
    
              Board newBoard = service.board().getmove(previousBoard).execute();
              service.scores().insert(new Score("WIN")).execute();
              ScoreCollection scores = service.scores().list().execute(); 

    Step 6: generate Mobile client libraries

    Solution

    Stuck? Download this file which contains the steps we just completed

    • Replace application: tictactoe-codelab with application: your-app-id

    And you're done!

    You've finished the codelab! Feel free to work on an Android client for the remainder of the time, or bask in the glory of your awesomeness!

    Thank You!