My favorites | English | Sign in

Google Code University

Google AJAX Search API Tutorial

Table of Contents


Audience and Pre-Requisites

This tutorial covers the basics of API- and event-based programming using the Google AJAX Search API. The pre-requisites include the material covered in our other tutorials on CSS, DHTML and Javascript, and Ajax.

What Exactly is an API?

An application programming interface (API) is the set of tools provided by an operating system, library or application which allow programmers to use its services or data. A good example of an API is a graphics library, such as OpenGL. A group of programmers created the OpenGL library by designing and implementing sophisticated graphics capabiliites into a set of functions such as:

glutWireSphere (radius, slices, stacks);
glutSolidTeapot(size);
glColor3i(red, green, blue);
This library of functions make it possible for programmers without graphics expertise to create scenes, animations, and graphical user interfaces which if not for the OpenGL API, they would not have been able to implement. All one needs to do to use the OpenGL API is include its libraries when compiling and linking.

Some APIs (OpenGL is a good example) require quite a bit of knowledge and practice to use correctly. The Google AJAX Search APIs are not nearly as complicated as OpenGL, but there are some things you need to do to get things to work right.

What is Event-Based Programming?

Most of us are familiar with the structured programming paradigm where we work with data through control structures such as if else, while, for, and so on. For example:

if (value == MAXLIMIT)
  value = newValue - oldValue;
else {
  while (true) {
    ...
    if (newValue == MINLIMIT) {
      for (int i = 0; i < newValue; i++) 
        ...
    else
        break;
    }
  }
}

The path through this program is defined by the values of the various data elements and the control structures. Contrast this with an event-based program, where the program sits idly waiting until the user does something. The path through such a program is controlled by user-generated events, as opposed to control structures operating on data.

The most important elements of an event-driven program are the event-handlers. These are functions in the program that are called in response to a user event. The events can occur in any order and at any time, which is quite different from the structured approach. You cannot assume that a user has entered data in some particular order or caused a sequence of events to occur in some particular order. You can't even assume anything at all has happened.

Events are recognized via special structures available in APIs or programming languages. For example, in OpenGL, we have an event loop and callbacks:

// create a window
glutCreateWindow("OpenGL");     
....

// register a callback
glutMotionFunc(myMovedMouse);   
// wait for events
glutMainLoop();               

Some APIs in event-based programming provide functions that allow us to register user-defined functions to be called when a particular event occurs. These user-defined functions are designated callbacks. In the code above, glutMotionFunc() is provided by the API, and myMovedMouse is a function that the programmer writes which is called when the mouse is clicked and dragged.

The API function glutMainLoop() is an event loop that executes continuously until an event occurs. Based on the event type, the appropriate event handler (callback) is executed. This program does not do anything until an event occurs.

Getting Started with Google's AJAX APIs

Google engineers have created a set of APIs using the AJAX programming model. This is inherently an event-based model. Let's start by looking at a simple example:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
  <title>Hello World</title>
  
  <!-- std apis -->
  <script src="http://www.google.com/uds/solutions/cscintro/stdlib.js" type="text/javascript"></script>
  <link href="http://www.google.com/uds/solutions/cscintro/stdlib.css" rel="stylesheet" type="text/css"/>
  
  <!-- base-styles for my demos -->
  <link href="base-styles.css" rel="stylesheet" type="text/css"/>

  <!-- main -->
  <script type="text/javascript">
  function main() {
    var log;
    log = new StdLog(document.getElementById("log"), "stdout");
    log.printLine("Hello World");
  }
  </script>
</head>
<body onload="main()">
  <h1>Simple Hello World</h1>
  <div id="log">Loading...</div>
</body>
</html>

Notice we are importing two API files: stdlib.js and stdlib.css. The first file contains a set of standard functions available for us to use in our html files. In main(), we create a StdLog() object and call its printLine method to place a window on the screen and print a string in the window. We call main() when the html file is loaded (in the body tag).

The second API file contains a set of css definitions for StdLog().

You can view the classes and methods available in stdlib.js by opening http://www.google.com/uds/solutions/cscintro/stdlib.js in an editor. We are using the StdLog object in the file above. Notice the use of DOM, DHTML and CSS in the methods of this file. You can view http://www.google.com/uds/solutions/cscintro/stdlib.css to see the CSS tags.

In this second example, we print an array. This shows some simple Javascript functionality and printing the results in the stdout window.

<!-- main --> 
<script type="text/javascript">
function main() {
  var log;
  log = new StdLog(document.getElementById("log"), "stdout");

  // print array forwards
  log.printLine("My array has: " + myArray.length + " entries");
  var i;
  for (i=0; i < myArray.length; i++) {
    log.printLine("[" + i + "] " + myArray[i]);
  }
  log.printLine("");
}

myArray = ["cat", "dog", "car", "house", "tennis", "skateboard", "baseball"];
</script>
  
</head>
<body onload="main()">
  <h1>Print an Array</h1>
  <div id="log">Loading...</div>
</body>

Now let's add some event handing. In this example, we create some html buttons. Pressing one button prints the array forward, and the other prints the array backwards.

  <!-- main -->
  <script type="text/javascript">
    var gLog;
    function main() {
      gLog = new StdLog(document.getElementById("log"), "stdout");
    }

    function printArray(fForward) {
      var i;

      gLog.printLine("My array has: " + myArray.length + " entries");
      if (fForward) {
        for (i=0; i < myArray.length; i++) {
          gLog.printLine("[" + i + "] " + myArray[i]);
        }
        gLog.printLine("");
      } else {
        i=myArray.length - 1;
        do {
          gLog.printLine("[" + i + "] " + myArray[i]);
          i--;
        } while ( i >= 0 );
        gLog.printLine("");
      }
    }

myArray = ["cat", "dog", "car", "house", "tennis", "skateboard", "baseball"];

  </script> 
</head>
<body onload="main()">
  <h1>Print an Array</h1>
  
  <input type="button" value="Print Array Forwards" onclick="printArray(true)"/>
  <input type="button" value="Print Array Backwards" onclick="printArray(false)"/>

  <div id="log">Loading...</div>

</body>

This program does nothing until the user presses a button - a classic event-based program. The onClick attributes call the printArray function with the appropriate value to indicate a forward or backward traversal through the array. Notice that main() is called in the body tag to set up the window.

Search APIs

Now we can take a look at the Search APIs, which are made available through the following:

 <!-- google search api -->
<script src="http://www.google.com/uds/api?file=uds.js&v=1.0&key=YOUR_KEY" type="text/javascript"></script>

Here is a program that allows a user to enter a search term, performs the search by calling Google's Search API methods and returns the top eight results. In order to do this search, the API methods use AJAX to send the query terms to the search engine. Then, DOM, DHTML and CSS are used to update the page.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
  <title>Print Search Results</title>
  
  <!-- google search api -->
  <script src="http://www.google.com/uds/api?file=uds.js&v=1.0&key=internal-solution" type="text/javascript"></script>
  
  <!-- std apis -->
  <script src="http://www.google.com/uds/solutions/cscintro/stdlib.js" type="text/javascript"></script>

  <link href="http://www.google.com/uds/solutions/cscintro/stdlib.css" rel="stylesheet" type="text/css"/>
  
  <!-- base-styles for my demos -->
  <link href="base-styles.css" rel="stylesheet" type="text/css"/>

  <!-- main -->
  <script type="text/javascript">
    var gLog;
    var gSearch;

    function main() {
      gLog = new StdLog(document.getElementById("log"), "stdout");
      gSearch = new GwebSearch();
      gSearch.setResultSetSize(GSearch.LARGE_RESULTSET);
      gSearch.setSearchCompleteCallback(null, searchComplete, [null]);
    }

    function startSearch() {
      var input = document.getElementById("input");
      if (input.value) {
        gLog.printLine("Search Results for: " + input.value);
        gSearch.execute(input.value);
      } else {
        gLog.printLine("*** Error. Enter a Search Term ***");
      }
    }

    function searchComplete() {
      if (gSearch.results && gSearch.results.length) {
        var i;
        for (i=0; i < gSearch.results.length; i++ ) {
          var result = gSearch.results[i];
          gLog.printLine(result.title + " @ " + result.url);
        }
        gLog.printLine("");
      } else {
        gLog.printLine("*** Error. No Search Results ***");
      }
    }

  </script>
</head>
<body onload="main()">
  <h1>Print Search Results</h1> 
  <div class="input-box">

    <input type="text" id="input"/> <input type="button" value="search" onclick="startSearch()"/>
  </div>
  <div id="log">Loading...</div>
</body>
</html>

The main() function sets up the window and then calls the GwebSearch constructor. We set the result size (to eight) and then define a callback (searchComplete()) which we implement using stdlib.js methods. Notice that we have access to the results array returned by the search engine in our callback.

The startSearch() method is called when the button event occurs. The key method call here is gSearch.execute(input.value) which uses AJAX to send the input value to the search engine and then calls the callback funtion when the results are returned.

For more information on the Search APIs, check out the API reference.

Finally, check out the following program which shows how to incorporate various searches in any web page, as opposed to printing results in a stdout window. Here is a short tutorial that takes you through building this program.

References

Google AJAX Search APIs Doc and Tutorial

Google AJAX Search APIs Reference