Google I/O 2012 – Building Web Applications using Google APIs and JavaScript Client for Google APIs


BRENDAN O’BRIEN: Hello, and
welcome to Google I/O 2012. Today, I’m going to be talking
about building web applications that use Google
APIs and the JavaScript client for Google APIs. My name is Brendan O’Brien. I’m a software engineering on
Google+, and I also maintain the JavaScript client. As the title implies, we’re
going to be talking mainly about the client, what it can
do, how you do that, and how you use it to consume
Google’s APIs. So a little bit about
our APIs. We provide many RESTful
APIs for most of our products and services. This includes Google+, Calendar,
Analytics, and over 35 more discovery-based APIs. We even announced a few here
at Google I/O. Hopefully you’ve seen some of
the sessions. Requests are typically made to
www.googleapis.com, which is Google’s APIs front-end. So I have an example here, since
it is a RESTful API. I can take this URL and just
paste it into my browser here. So what this one’s going
to do– let me go back real quick– as you can see in the URL here,
that urlshortener/v1. This is going to go to URL
shortener API at version one, and take this shortened URL,
and give us back the long, full URL for it. So if I paste that in, we should
get some data back. And here we are. We have a JSON blob, and
we can see one of the fields is longUrl. www.google.com. So that’s what the short
URL translates to. And there’s some other fields
in here that might be useful for you as well. So we also provided several API
clients to make accessing the Google APIs easier
for you. We have a total of nine
clients right now. Besides just JavaScript, there’s
Java, Objective-C, Python, and many more. And I have a link here, if
you’re curious later, to see all the clients that
we currently have. So before, if you wanted to
consume Google APIs, you had to do it from your web server,
using one of the server-side scripting languages– Java, Python, something
like that. So in order to make API calls,
your code in the browser would have to call back to your web
server, your web circles makes a call to the Google APIs server
to get a response back, and then it has to pass that
response back to the browser. So a lot of logic must exist
on your web server to make this possible. Well, with the JavaScript
client, you can make these calls directly from
the browser. This makes your web server a
bit simpler, and also just makes it so that you
can make these direct calls a bit quicker. So I’m going to do a
quick demo using the JavaScript client. And I have a little snippet
of code here. This is basically all the code
that exists in the demo that I’m about to show you. This is all that’s needed to
load an API and then make calls to it and get
a response back. So here is this demo. Again, I’m going to use the URL
shorter API as an example. And I’m going to take a short
URL and expand it out into a long URL. And you’ll see that I’ve
pre-populated this field here with the same short URL
that we had before. So, if we expand it, as we
expect, we see that this short URL expands to www.google.com. And like I said, the code you
saw on the previous page is all the code that’s running on
this page besides HTML markup and the little things to make
it slightly pretty. So now that we’ve seen a demo
and seen what it can do, let’s talk in a little bit more detail
about what it provides and what it can do. First, a note on
compatibility. We support the four major modern
browsers, including Chrome, Firefox, Internet
Explorer, and Safari. We also have built-in support
in the JavaScript client for the OAuth 2.0 authorization
protocol so that your applications can be authorized
to retrieve sensitive or protected user data
on their behalf. And we also support many APIs,
as I mentioned earlier. I’m just going to click through
really quickly to the Google APIs Explorer. This is where you can see a list
of all the APIs we have and what versions they’re on,
and it also allows you to see what methods are available
on each API. What’s also really cool is you
can run these methods directly from the Google APIs Explorer
and play around with them before actually implementing
any code in your project. So it’s very useful. And I’ll be doing a little
bit more with the APIs Explorer later. And also, if you are interested
and you attend the code lab, we’ll be doing
a lot more work in the Explorer as well. So let’s just have a
quick look at it. So we can see the list
of APIs here. We can scroll down and see
the various versions. There’s a little description
on the right of the API and exactly what it does. So here’s URL shortener down
here at the bottom, the one we’ve been using. If I click through it has all
the methods that are available on URL shortener, what their
names are, and again, a quick little description. You can also see, at the top,
there’s a link to the full documentation for this API. And that will tell you in detail
what the calls are that can be made, how to make them,
what their response is going to look like, et cetera. So we’ll come back to this
later when I actually demonstrate exactly how you can
make calls from the APIs Explorer to learn about
these calls. OK. So you’re probably wondering,
well, what do I get by using the JS client? Well, the first thing is we have
a method that allows you to make these RESTful
requests. All of our APIs are based on
the REST protocol, which is also the basis for HTTP. URLs typically identify
resources, and then you specify the HTTP verb, such as
POST or PUT or GET, that is going to do an operation
on these resources. So I have another snippet of
code here that shows how to make a REST request in the
JavaScript client. The method for that is
gapi.client.request. All methods are on the
gapi.client namespace, or, for our authorization method,
the gapi.auth namespace. So this is the same example
I’ve been using so far. This is the URL shortener API. And we can see in the path,
like we saw before, I list first the API I want, URL
shortener, and then the version of it that I’m
trying to access. And then, as I mentioned,
there’s a resource at the end. URL is the resource we’re
trying to access here. And then we pass in a few params
to let the API know exactly what we want to do. Since we pass in a short URL,
it knows that we want to get back information about
this short URL. In particular, what
does it expand to? What’s the long URL? So when you call
gapi.client.request, you get back a REST request object. It hasn’t actually made
the call yet. In order to make the
call, you call Execute on the REST request. It’s the only method
to find on it. And it takes one parameter,
a callback function. And I’ll be talking about
that in a little more detail later as well. So the other way you can make
requests, or another request format that we support,
is JSON-RPC. When you make the request, it’s
encapsulated is JSON data in a POST body. And the response is always JSON,
as the name implies. So again, I have an example up
here of the same URL shortener that we’ve been using. And here you can see
the signature looks a little different. It says gapi.client.urls
hortener.url.get. So if you remember from the
APIs Explorer, that’s the exact name of the method that
we’re trying to execute. And we can see, we can just call
it directly, pass in our parameters that we’re interested
about, and again, we get back a request object. This is now an RPC
request object. But it’s very similar
to REST request. It has one method
on it, Execute. You pass in a call back, and
when the function returns, you can play around with
the response. So, I also said that we have
a built in mechanism that supports OAuth 2.0
authorization and authentication. Essentially, what you do is you
create a client ID– and we’ll be going over that later
as well– which identifies your application. And you also gather a set of
scopes that you’d like to have access to. So if you’ve ever installed an
Android application, for example, it tells you what this application wants to access. Does it want to see
your location or maybe read your profile? So these are the kind of things
that scopes identify to the OAuth server that you want
to access for this user. So here in this example, I have
just a random client ID. And then I have one scope that
I’m interested in here. And this is the Calendar
scope. So this will ask the user, this
application would like to access your calendar, possibly
read and also possibly manipulate. Is that OK? And we’ll be seeing an example
of that later. So the interface to do all OAuth
2.0 authentication is gabi.auth.authorize. You pass in the client ID I
mentioned, the scopes, and you can request multiple
scopes if you need access to multiple APIs. And then we have this immediate
value, which I’ll be going over a little
bit more later. Now, that’s all contained in
one object, so that’s the first parameter. The second parameter is another
callback method. And this will be past the result
of authentication. And if it’s successful, you can
continue on and use your application. If not, you’ll need to handle
the error somehow. So now we know what
the Google API’s JavaScript client can do. And I’m sure you’re curious,
how do I do that? I’ve shown you some brief
examples, but now I’m going to go into a little bit more detail
about how exactly we can do that and how
that works. So two things I want to go
over before we begin. The first is the APIs console. This is where you create an
API key and a client ID. Both are used to identify your application when making requests. And again, we’ll be talking
about those more detail when I go over authorization. This is also where you activate
the APIs that you’re interested in. So you saw a long list of APIs
in the APIs Explorer. Well, you turn on the various
APIs that your application is going to need access to. And you can do more in
the APIs console to manage your project. You can change the quota
for the APIs. They’ll have a default amount of
quota that they’re allowed to access every day. But you can request more
if you need more. If your application’s become
very popular, then you might need to do that. This is also where you
manage billings. A few of our APIs are paid APIs,
and you have to set up billing there. And you can do team management,
as well, to add more members to your project
so that they can go in and also change these settings. So I showed you the APIs
Explorer briefly. This is, as I mentioned, a
great starting point for documentation. First, you can just go through
the list of all the methods that are available on
the API and get a brief overview of each. And as you saw, there was
a link to the full documentation, so you can find
out just everything you want to know about this
particular API. You can try the API calls out
from the Explorer as well. And we’re going to do
that right now. So here’s that short
URL again. I hope you’re noticing
a theme. So we come back into the APIs
Explorer, and I want to find the URL shortener API. So here are all those
methods again. And the description of the
first one says “expands a short URL or gets creation
time and analytics.” Well, great. That’s exactly what
we’re looking for. I want to see what this
short URL expands to. So I click into that, and it
gives me this form where I can fill in the parameters
for this particular method and let it go. As you can see, the bold
red ones are required. Let’s get that up
a little bit. So I’m going to paste in that
value here that we had before for short URL, and execute
this method. Now, if we scroll down, the
APIs Explorer shows us the request that was made. We saw this URL in the beginning
of the presentation. And then it shows the
response as well. And this is the same response
we saw earlier, a JSON response where long URL has
the value that we’re interested in. OK. So now that we’ve done
that, we’re ready to use the JS client. Well, to load it,
the URL is here. It’s https://apis.goo
gle.com/js/client.js. Now, the way the JS client
loads, it loads asynchronously in two phases. We do this, obviously, so that
it doesn’t block your page and make performance terrible while
you’re waiting for the page to load. But this also means you need to
know when the JS client is actually loaded and
is ready to use. So to do that, we have added
this onload parameter, URL parameter, that you
add to the URL. And it specifies a global
JavaScript function that it should execute when the JS
client is ready to use. So let me just highlight
those two things here. We can see the URL for the JS
client and the script source with this onload parameter. And it’s pointing to this global
init function which is defined above. And once the unit executes, we
know that the JS client has loaded, and we can run off
and start consuming APIs. So the first of the two ways you
can make requests in the JavaScript client is by
making a REST request. When you go into the
documentation, the full documentation, for each API,
they tend to describe the APIs in terms of REST. So, what are the URLs that you
need to construct to access various resources? What are the methods
you need to make? The HTTP methods you
need to use to manipulate these resources? So here, again, is the
REST request method. We just call it
gapi.client.request. And it takes one argument,
which is what we call a bag of arguments. It’s just an object with key
value pairs of one required and several optional
parameters. So let’s just go through
those very quickly. The first is the ‘path,’ the
path to which you’re making this request, that identifies
the resource that you’re trying to get or manipulate. Earlier, we saw that, for the
URL shortener, it was urlshortener/v1/url. So that last part, /url, is
the resource that we’re interested in. Now you need that whole path
in the gapi.client.request, and we’ll see that
in a second. The next parameter is ‘params.’
These are URL parameters that will be
serialized and encoded and added to the path when
this request is made. When going through the
documentation, some of the APIs have URL parameters that
you can use to control how the method is executed, or maybe how
the response comes back. And so this is where you would
add those parameters. Next, we have ‘method,’ which
is the HTTP method. This is, again, optional. It defaults to a GET. But you can do, again, many APIs
support POSTs and DELETEs and INSERTs, in particular,
for deleting and inserting more resources. And then next we have ‘headers.’
this is a key value pairing, again, of headers– and it’s optional– that you can send along
with your requests. These are, again, just
HTTP headers. And some of the APIs have some
headers that you can set, again, to control or manipulate
the request as it’s being made. Next, we have a ‘body,’
an HTTP body. Particularly when doing inserts
and making REST requests, you’ll serialize a
JSON object into the body, and that will get sent to the API. And finally, we have
‘callback.’ This is, again, optional. But it’s a callback function
that will be executed when the request returns. Now you don’t have
to provide this. If you do, the request is
executed immediately, because it has a callback. If not, you get the REST request
object back that we saw earlier. And then you can call execute on
that, and that’s where you would pass in the callback
function. So here’s an example. I’ve switched APIs now to the
Calendar API, because it works very well for this example. So, we see in the path that
I want to specify the API inversion that I’m interested
in– calendar, v3. And the documentation
will mention this. And then I want to access
me, as a user. So I put in users/me. And in the documentation, “me”
is a special keyword to let you know that it wants to access
the currently logged-in users, so the users of your
applications, their Calendars. And then the last
is calendarList. I want to list all the Calendars
that this user has. So then I have the method as a
POST, because what I want to do for this request is insert
a new calendar. So I’m posting to
this resource to insert a new value. Next, I set one header value,
which is content type application JSON to let the
API server know that I’m sending JSON data along
with this request. Now, this is actually
the default. It’s always included. But I’ve included it here
for illustration of the headers parameter. Next, we’re passing
along a body. So, as I mentioned, we’re
inserting a new calendar here, and this is how the API
expects the new calendar to be inserted. You pass in a calendar
resource, which the documentation describes, to
create this new calendar. So I’ve included one parameter
that’s required, the ID, and that’s just my demo email
address here. And I’ve also included an
optional parameter value, the selected true. And this will mean when you look
at the Calendar UI, that this calendar will be selected
by default and you’ll see your events in the Calendar UI. And then I pass in a callback
so that this request will execute immediately. And when it returns, it will
execute this function. So let’s talk a little bit
about that callback. So the callback takes
two parameters. The first is called
jsonResponse, and this is the response from the response
body, parsed as JSON. This will actually be the
Boolean value false if the response is not valid JSON or if
it’s just not JSON at all. This could be the case for a
few APIs, but it’s kind of rare that you will not
have a jsonResponse. If you don’t, we also provide
rawResponse, which is the full HTTP response as a stream. So this is actually JSON. Even though it is a string, you
can parse it out into an object that contains the body
response, the headers, which is another key value pairing and
object that were sent as response headers, the status of
the request, and then the status text as well. So if you’re interested in
anything besides the response in the body– the headers, the
status, or the statusText– you would find that
in rawResponse. So the other request format that
we can use is JSON-RPC. And there’s actually several
ways we can make a JSON-RPC request using the JS client. The first is by just directly
creating one of these objects. So we do that with
gapi.client.rpcRequest. And the format, as
you see here, is it takes three arguments. The first is the method
you want to execute. The second is the API version
of the API that you’re trying to access. And then the parameters for this
actual request are passed on as the third argument here. So I have a quick example. This request is going to search
the Google+ profiles. So that method is
plus.people.search. You can find that, again,
in the APIs Explorer. There’s method name and what
the current version is. In this case, it’s V1. And then we pass in an object,
key value pairing, of the parameters that this
method expects. So it only has one required
parameter, and that’s the query you want to make. And so I’m going to look for
every profile on Google+ where the person’s name
includes Lewis. So that returns back a
RpcRequest object to me, and then I can execute that and
pass in a callback. So you may remember from before,
I didn’t use that RpcRequest method when I
introduced JSON-RPC. I called a method directly on
the gapi.client namespace. Well, this is how
you set that up. We have a gapi.client.register
method, which registers this method that we’re interested in,
so that we don’t have to always put in the method
name that we want. And it’s particularly
the API version that we’re interested in. So when I do this call here,
gapi.client.register (‘plus.people.search’) and pass
in the apiVersion, that’s going to register this method. And remember that the version
that we’re interested in for this method is V1. So that method registers in
the gapi.client namespace. We do this to avoid polluting
the global name space and keep it as tight as possible. And the way we register it is by
separating on the dots and the method name and turning
that into a namespace and function name. So plus.people.search becomes
gapi.client.plus.people.search. And then this is a method. So when you execute this method,
you pass in the params for the RpcRequest that
you’re trying to make. And again, it returns to
an RpcRequest object. So in the example down here at
the bottom– let me just highlight that real
quick– this is where we call the method. I pass in the same query that
I was interested in before. I want to find everybody
named Lewis. And I get a request
object back. And then I can execute
that request object and pass in a callback. So now, with JSON-RPC, you can
load one in particular API, the entire API, all at once so
that you don’t have to, for example, register every single
one of the methods. We looked at URL shortener
earlier, and there were three methods. Well, some have quite a
few more than that. They may have three dozen,
for example. And you don’t want to have to
put in your code a line gapi.client.register for each
one of those methods if you’re going to be using them
most of the time. So the JS client provides a
convenient method called load, gapi.client.load, which will
load the entire API surface, register all the methods, and
when we do that again, it will remember the version that
we’re interested in. So this is a nice convenience
method that will save us some time and some coding
in our code. So the way this works is you
pass in the name of the API you’re interested in. This is typically the first
part of the full method description. So in plus.people.search, the
first portion was “plus.” That’s API name. And then we pass in the version
we’re interested in, V1 in this case. And then it also takes as a
third argument a callback to let us know when that API has
loaded, all the methods are registered, and we can start
making requests– registered method requests– on that API. So this one, for example,
registers all the Google+ API methods. So we saw how to make
a JSON-RPC request. We saw a couple methods of
making a JSON-RPC request. And in all of them, we
pass in a callback to this execute method. So this callback is very similar
to the REST callback, in which we get two parameters
passed to this callback. The first is JSON response. Again, this extracts the
returned value from the HTTP request, parses it
at JSON, and then passes it as this parameter. And again, this will be false
if the response is not valid Jason or not JSON at all. But of course, since we’re
working with JSON-RPC, that is going to be extremely rare,
if it ever happens at all. But, just in case, we include
the rawResponse, which is the entire RPC response
as a string. It’s always present, but
you may not always be interested in it. So again, if it’s not JSON,
you can do your own custom parsing on this. But again, I don’t think
that’ll be a very common use case. So one cool thing about JSON-RPC
requests is we have built-in support for making
batch requests. So you have a snippet in
your code that makes many requests in order. And for each one of those, it’s
going to be making an HTTP round trip. And these are HTTPS
round trips. All of our requests
are made on SSL. So they can be quite costly. If you’re making many of them,
it would be nice if you could make multiple requests with
just one HTTP round trip. Well, this is what batching
allows you to do. All requests are sent off and
executed in parallel, and then they all come back at
the same time with their various responses. So let’s go through, quickly,
how you use the JSON-RPC batching. Well, the first step,
up at the top, is create a new batch. And that method is
gapi.client.newRpcBatch. And this gives you back
a batch object. We can then add requests to
the batch object, and when we’re done adding requests, we
can execute it and go and get our responses back. So the next two segments
we see here is the add method, batch.add. Let me show you first
in the code. I created two RpcRequests. Just for illustration, one is
a direct creation, where I call RpcRequest and pass in the
method and the API name that I’m interested in. And this one’s going to search
for all Google+ profiles where the person’s name
contains Larry. And then I create another
request from the register plus.people.search method. And you can see, in this case,
it’s a little bit simpler. All I have to pass in now is the
query parameters that I’m interested. And so then this request is
going to search for all people on Google+ name Sergey. So now I want to add both these
requests to my batch and then execute the batch. Well, in the batch.add, the
first parameter, the first argument to this method–
it takes two– is required, and it’s the
request you want to make. Makes sense. The second argument is another
one of these bag of args with some optional parameters
in it. The first is going to be the
ID for this request. So obviously, you’re
making multiple batched requests here. When it returns, it may not
necessarily be in the same order as you added them
to the batch. It just depends on when
those requests finish on the back end. So if you want to be able to
access the response from this entire batch, you’ll need
an ID for that. So for the Larry request,
I’ve added an ID. We’re just going to call it
“Larry.” So that will identify my response. I’ve also passed
in a callback. And I defined this callback
up above. Right now it’s just
an empty function. But you can see it’s got the
same callback signature that we’ve seen before. For the second request, I add
it, and I don’t use any of optional parameters. Now, if you’re interested in
the response for a batch, you’re going to want one of
the two, ID or callback. You’ll either want the ID to
extract a response from your batch response, or
the callback. Because this individual callback
will be called with just the response for this batch
operation, not for the entire thing. So once I’ve added two requests
to my batch, I define a batch callback. Again, this is just an empty
function for illustration purposes, but you can see that
the signature is similar to what we’ve seen before. I’m going to go over that
in detail in a second. And then I execute that
batch and pass in the batch callback. So a little bit about
these callbacks. As I mentioned, there
are callbacks for individual responses. You saw we added one for the
Larry request, but not for the Sergey request. And then we also, when we
executed the overall batch operation, we sent in another
callback method. So how do these get executed
when the response returns? Well, individual batch
callbacks are all executed first. You’re not guaranteed the
order, but you will be guaranteed that those
will execute first. And then when all those are
done, the overall batch callback is executed. So what gets passed to these
callbacks when the response has returned? Well, again, it’s very similar
to what we’ve seen before for JSON-RPC requests. The first is a JSON response. This is the response parsed as
JSON, so you get a JavaScript object back. For individual callbacks, this
is the response, as I said, just for that particular
method. So the Larry callback we saw
will be executed and only receive the response from the
search for people named Larry. It will not see the response
for Sergey in this JSON response. For batch callbacks, this
is all of the responses. And it’s a map of the batch ID
to the particular response for that batch operation. And then the second parameter is
the best response, which is the same overall ID to response
mapping, but this is just a string. What’s nice about this is it
always includes the full batch response for both individual
callbacks and for the overall callback. So at the end of one of your
individual callbacks, you’re going to need to access data
from another batch operation you’ve made. You could either look in this
batch response, or you can also use the overall batch
callback, as that will receive the ID to response mapping as
well, but that time in the JSON response parameter. So, I have an example down here
from our previous slide. Those requests we made
in the batch. We get a response back,
which is just an ID to response pairing. The first ID is Larry, since we
specified what ID we want that response to be
identified with. And then the second one is just
a random string that the JS client automatically assigned
for you so that it has a unique ID identified
with it. And then each one of these has
the individual responses, the search results for Larry and the
search results for Sergey. OK, so now we’re going to
diverge just a little bit. We saw the two request
formats that you can use with the JS client. One is the RESTful style,
the other is JSON-RPC. Well, we also provide an option
for using a different transport for making
these requests. So, astute observers will notice
that we’re making calls to www.googleapis.com
from your domain. Your application is running
on a different domain. We’re not going to let you
run on googleapis.com. Well, you can’t make
XML HTTP requests to a different domain. That’s not allowed
by browsers. Well, the JS client gets around
this in a somewhat clever way, but it’s also a
little bit bulky, and it’s proprietary as well. But there’s a new transport out
there called CORS, which stands for Cross Origin
Resources Sharing. So if the server that is
accepting XML HTTP requests support CORS and says CORS
will be allowed for these requests, then you can
make a CORS request. And so we’ve implemented
this on googleapis.com. So you can make direct
XHRs to Google APIs and access our APIs. So these are constructed similar
to REST requests, because we’re just making HTTP
requests and, as you may know, that those are based on
the REST protocol. So I have a snippet here, and
what’s cool about this snippet I’ve included is you can take
all this code, copy it into a page, make a request,
and it will work– well, with one caveat. I’ve provided a dummy
API key here. But if you change that and put
in your own API key, this would work just fine. So we can see, in this
example, some of the translations that
we need to make. So when you open an XHR, the
first parameter is the HTTP method you want to make. So that was provided in
gapi.client.request. Here’s where you put it here. And then the second parameter is
where you want to make the request to. So you can see, I have
to include a bit more in this example. I have to include the domain
I want, www.googleapis.com. And now there’s this new
parameter key with this sort of encrypted value here, and
what the heck is that? Well when making requests,
you must identify your application, either using
an API key or client ID. We’ll get back to this again a
little bit more when we talk about authentication. Normally, the JS client, you
set the API key once, it remembers it, and for every
request this key is set. Well, if you’re making a CORS
requests, you’re not using the JS client. And so you need to remember
to add that. The same is true for this
request header here, Content Type Application JSON. I included that in the REST
example earlier, for illustration purposes, and
mentioned that the JS client will handle this for you. Well, if you’re making direct
requests through CORS, you need to remember to
set this as well. The callback is set by sending
a function to the onload parameter and getting the
response from the XHR response text. And we send the payload in the
body through the xhr.send. So in this example, I’m actually
inserting a long URL to try to get back the shortened
version for it. So when I send the request,
I pass in the long URL, www.google.com. So why did I mentioned this? Well, first, we just think
CORS is pretty cool. It’s a native transport, which
means you don’t need to use, as I mentioned, our proprietary,
cross-domain handling method, which
means it allows for faster requests overall. It’s also standards-compliant,
non-proprietary, and it’s native to most major
modern browsers. So I encourage you, if you’re
interested, to try out CORS request, but with a
couple caveats. One is that browser support
is currently not quite as expansive as the JS client. So the JS client will handle
pretty much any major modern browser that your users
are using, but CORS is not quite there yet. Also, since it’s not currently
implemented in the JS client, if you stop using the JS client,
you’ll miss future updates to the JS client. So that’s why I mentioned
to use, maybe, as an experimental basis. Or perhaps you know that your
users are only using compliant browsers, and so you just want
to use CORS instead. That’s a great use
case for that. So I’ve included a useful link
here to caniuse.com, which will tell you which browsers and
which versions currently support this. So let’s summarize, first, the
two request formats that I’ve mentioned here. The one is JSON-RPC, and
the other is REST. So, which allows you to set and
read HTTP method headers and bodies? Well, the REST does,
as we saw. It had those various
parameters that you can pass in. JSON-RPC does not. It only allows you to
pass the parameters that the API expects. What about batching? Well, JSON-RPC has built-in
batching. We saw that earlier. It was pretty easy to do. There’s just a few method calls
you need to make to get that to work. REST also supports batching,
but it’s quite a bit more tricky to do, and it’s not
built into the JS client currently, so you’ll have
to do it by hand and really kind of messy. I definitely suggest, for right
now, using JSON-RPC if you want to do batching. And we also saw that, with
JSON-RPC, we can auto-load full APIs, register all those
methods, and then make these really simple requests on them
but just passing in the query parameters that the
API expects. Whereas, with REST, you pretty
much need to construct every single request manually
by hand. We also have two transports. One is built into
the JS client. We call that XD3. And the other is CORS,
as I mentioned. Well, if you use the JS client,
then your requests are automatically formatted. So I mentioned before that
CORS requests generally translate well to
REST requests. Well, you can also make a
JSON-RPC request using CORS if you get the format right. Well, the JS client handles
the format for you, so you don’t have to worry
about that. And it can be maybe a
little bit tricky. So CORS doesn’t allow you to do
that, at least currently. The JS client is fully
cross-browser compatible. We saw all the clients
that it supports. That’ll cover most modern
browsers, major browsers, whereas CORS only has
partial, currently. However, CORS is native to the
browsers that do support it, whereas the JS client,
obviously, is not, and you need to download that into
your application. JS client has built-in Auth,
however, and allows us to make these OAuth 2.0 authentication
and authorization, whereas CORS does not. Those endpoints don’t support
CORS currently, so you’ll still need to use the JS client
if you want to do authorization. Let’s talk about
authorization. This is the last major
piece of the JS client that it provides. So just a very quick
OAuth 2.0 overview. This is probably review
for most of you. It’s in the webinar, if you’ve
seen the webinar. And there’s also some
talks at Google I/O that talk about OAuth. But just a quick overview. I found a great quote
for this. “OAuth is a security protocol
that enables users to grant third-party access to their web
resources without sharing their password.” So normally, if we did not have
OAuth, the user would have to give your application
their username and password so that you could sign into Google
for them and make requests to the Google
API servers. Well, with OAuth, that’s
no longer necessary. Instead, the user logs in
directly to this third party– in this case, the Google
APIs server– and gets back an access token. And then your application uses
that access token to make requests to protect
your resources on the user’s behalf. So I have a few useful links
here to the OAuth working draft, a page on the Google
Developers page about OAuth and how to use it and everything
that provides and what we support, and then a nice
intro from universe.com, which is where I got this great
quote here that briefly describes OAuth 2.0. So let’s look at that, quickly,
in an example. I want to show the difference
between authorization and authentication, because
I think I might be a little bit unclear. So this example, as it says,
is going to retrieve my profile name and photo using
the Google+ API. So I click this Authorize
button here. And the first thing it does is
pop up a Google– this is accounts.google.com,
as you can see. This is the Google login page. So I need to provide my email
here and password. And then I sign in. That’s the authentication part
that authenticates me with Google servers only,
not your servers. And then the next page it
brings me to is the authorization page, where
the user authorizes your application to make requests
on their behalf. So we can see that my app, I/O
2012 JS Client Demos, is requesting permission to know
who I am on Google, so it can get my profile name
and picture. And if I expand that, it tells
you a little bit more. Associate you with your
Google profile. So this segment here comes from
those scopes that you pass when you do
gapi.auth.authorize. And again, there can
be many of these. So the user can click Allow
Access or no, No Thanks, I’m not interested. Of course, I’m going to click
Allow Access here. And there you go, it retrieves
my name and my little Android figure avatar here. So I’ve been talking about the
API key and client ID a bit. Let’s go over what exactly
those are. Now, if your application is
accessing unprotected resources, then all you
need is the API key. And all it does is identify your
application is accessing these APIs. And that’s important for quota
and things like that. However, for protected
resources, we need to make sure that you’re authorized
to access these protected resources. And so that’s when you exchange
a client ID to our Google authorization servers to
get an access token back, and then you pass that access
token with each request to access-protected resources. So let’s go over, really
quickly, where you get this API keys and client IDs. So I’m going to the APIs console
here that we saw earlier, and I’m going to
create a new project. And when we create the project,
the first place it takes us is to the
Services page. And this is where you turn on
all the various APIs that you’re interested in. I’ve been using a
few examples, so let’s turn those on. I’m going to turn on
Calendar first. And you can see what it does is
it sends me to a Terms of Service page to make sure I
agree to the terms of service, first for Google APIs
is in general– I accept– and then for the Calendar
API in particular. I’m going to go ahead and
agree to those as well. And then we’ve been
using Google+. Let me turn that one on. And again, there’s the
Google+ Terms of Service, so I accept that. And finally, we’ve been using
URL Shortener as well. So let’s turn that one on. And in that case there is no
Terms of Service for the URL Shortener, so we don’t
see anything there. So now that I’ve turned on the
APIs that I’m interested in, we’ll go to the API
Access tab. And we can see already under
Simple API Access that there is an API key here. Just highlight that quickly. This is that key that sent along
with the request you saw earlier, and it will identify
your application for unprotected resources. However, if we want to access
protected resources, we need an OAuth 2.0 client ID. So let’s create one with
this blue button here. First thing you do is put
in your product name. So when we saw that
authorization window, it said I/O 2012 JS Client Demos. Let’s put that in. You can also put a logo, and
this will show up on that same page, too, to identify
your application. I’m just going to skip
that for now. So it asks you what your
application type is. Of course, in this case, we’re
building web applications, so we choose Web Application. And then down here it asks for
your site or host name. I’m going to expand this to get
a few more options here. So this first box, Authorize
Redirect URIs, is not going to apply in our case, because we’re
not doing that kind of authorization. If you go to the OAuth 2.0 talk,
they’ll talk about that a little bit more and
what that does. We’re just curious about this
authorized JavaScript origin, because we’re making JavaScript
requests. So you can see here, it’s
defaulted to www.example.com. Well, as a developer, this
is the domain that your application is running on. Well, let’s just say mine is
running on google.com. Now, when verifying these
origins, they need to match exactly. So I have the HTTPS
protocol here– that needs to be listed– and then the full domain. And also, if you’re going to
be using a port, the port should be listed here. So I’m going to go ahead and
create this client ID to run my application on secure
google.com. And now we have a client ID. So this is what’s used to pass
to the authorized call to get back an access token so that
your application can use that access token to start
making requests. Now, again, if you’re using
the JS client, when that access token gets returned, the
JS client will save it for you locally, and then whenever
you make a request, that access token will automatically
be sent. Now, if you’re sending an access
token, you don’t also have to send an API key,
but it doesn’t hurt to. So I generally recommend to
always set the API key. And then, even if you’re using
a client ID, the access token gets sent as well, and
everything works just fine. OK. So I’m just going to go over
a code snippet here. And again, I included all this
code because this is just about everything you need
to do to make a nice authorization experience
for your application. So I’m going to go through
what this does. First, at the top here, we
have this global init function, which is going
to be executed when the JS client loads. We saw that earlier. First thing I do is
I set the API key. Now, I have a variable API key
above here that I don’t show, but this is the key you saw
in the APIs console. And then the next thing I’m
going to do is call this checkAuth function here, which
is going to make a gapi.auth.authorize call. And to that, I passed the
client ID that we just created, the scopes that I’m
interested in– and we saw we can have Calendar, maybe, or if
you’re using Google+, you want to say that you’re going
to use the Google+ scope– and then the last value I
pass is immediate true. Now, what this is going to do
is do a behind-the-scenes check to see, hey, has this user
already authorized your application? If so, terrific. And if they’re signed in, of
course, we’ll give you back an access token and you’re
off and running. Otherwise, you’re going to need
to send the user through the authorization flow. So when this returns, it’s
going to call this handleAuthResult function and
pass in an Auth result. We need to check that Auth
result to see, first, if it exists, and if it does,
make sure that there’s no error there. And if there is an error, we’re
going to need to handle that somehow. Otherwise, we get an access
token back and we can make API calls. Great. But if we have no AuthResult
or an error– and an error would be this immediate
has failed– then we need to send them
through the full flow. And to do that, I set this
handleAuthClick method to an onClick handler for an
authorized button on the page. Now, it’s important that you
have this function kicked off by a user-initiated event such
as a click or keydown, because, as you saw earlier,
the flow uses a pop-up, and you could trigger pop-up
blockers if you try to do it just programmatically. So here’s that AuthClick
method down here. And again, I’m calling
gapi.auth.authorize. Pass the client ID in
the same scope. But this time, I say I want
the immediate mode false. Turn it off. And this will send the user
through the pop-up flow that we saw earlier. Then we’re passing the same
handleAuthResult because, when we do get a response, an
AuthResult, then we know we’re good to go and we can
go off and running. So one more thing I want to
mention is when you get this access token, it expires after
a certain amount of time so that you can’t use it
indefinitely to make spammy applications, for example. Well, the response has another
field in it besides access token, called expires_in. And this is the value in seconds
until this access token expires. So what I’ve done in
this example here is I take that value– it’s in seconds again– and
I subtract 5 minutes– 5 times 60 seconds– and then convert that to
milliseconds So that I can do a set timeout to do the same
check off we saw before. And this does that background
check to get your access token. So it can happen without
interrupting the user while they’re using the application. And so by doing it this way,
you ensure that you have a fresh access token
all the time. I should also note that this
field expires and does not auto update. So there is a method,
gapi.auth.getToken, that gets back this token value with
the expires_in field. Well, that field
doesn’t update. So don’t trust it when you
call gapi.auth.getToken. Only trust it in this
handleAuthResult callback So you make and authorized
call. Like I mentioned, this is done
for you automatically by the JS client, but if you’re
using CORS you need to set this yourself. And the way you do that is you
set up one header, called Authorization, where the value
is the string bearer plus the access token. And this is an example of an
access token which is, of course, long since expired. And that’s it. So I’ve included some
links here for you. The first is the home page for
the JavaScript client. The second is the discussion
forum. If you want to ask questions,
I’m on the discussion fairly regularly. And then an announcement blog. The name is wrong there, but
this is the link to the announcements log where I
announce various new features for the JS client. And then I also wanted
to call out a couple sessions and code labs. There is a code lab for this
particular session that I very much encourage you to go to. It will go through all these
things I’ve talked about in much more detail, and you’ll
actually build an application using the JS client. You can also go to Optimizing
Your Code Using Features of Google APIs, which is a session
on making your APIs access more performant. And finally, a session
on OAuth 2.0 and how exactly that works. So thank you very much
for coming today. I would like to open up the room
for questions if you have them, and if so, please use
the microphone so that the folks on video can hear. Thank you.

6 thoughts on “Google I/O 2012 – Building Web Applications using Google APIs and JavaScript Client for Google APIs

  1. I take it you have never used Google Docs. Google 'powerpoint' files are called 'Presentations'. Its fair to ask they turn this into a presentation file. I much rather read it then listen to it on video.

  2. The original page from Google IO is here:
    developers.google.com/events/io/sessions/gooio2012/600

    It has the link to the presentation as well

  3. 17:25
    I'm trying to learn how to do this, but I have no idea how the calendar API knows to use the 'insert' function from just the POST method being specified and without insert being mentioned in the path since the 'watch' function of the calenarList object also uses the POST method…  sorta scratching my head

    https://developers.google.com/google-apps/calendar/v3/reference/calendarList/insert

Leave a Reply

Your email address will not be published. Required fields are marked *