[MUSIC PLAYING]
Hi everyone, and welcome to this week's Google Developers
Live for the Google Drive SDK.
I'm Steve Bazyl.
Today I want to talk about a new feature that is rolling
out for the Drive SDK that is particularly of interest to
people who are writing JavaScript client side
applications.
And this is improved CORS Support.
The Drive SDK has had CORS Support for most of the API
for a while now.
Certainly things like using the RESTful API, and even
downloading resources has been working fine.
But one piece has been missing.
And that's support for uploads.
And of course, since we want to encourage you to store
files in Drive, that's a very important part.
But starting just actually the past couple of days, and still
rolling out, is CORS Support for uploads.
And I want to show you how that works.
And then take a look at the code.
I built a little sample up last night just
to show this off.
And it's really simple.
It's got a Google+ sign-in button and we'll do a little
drag and drop to upload some files.
So I want to switch over to that.
And you can see here we just have a sign-in button.
I'm going to sign in really quick here.
You may not be able to see the whole approval screen, but
it's just standard Google+ sign in.
And then we have a nice little drop zone.
So I'm going to just drag--
I have a couple of files here, some PNG.
We'll drag that on, and then we can see here that we have
the metadata from that file.
You can see that it was created.
And if I go into Drive, you see I have
this untitled document.
And we'll talk about why we don't have a
title in just a moment.
But I want to switch over to the code and
show what this is.
So you can see here the page is very simple.
We have just a Google+ sign-in button, our drop zone, and
actually this upload button isn't even used anymore.
And of course, just an area for results.
And then the rest of the script is our code.
One thing you'll notice is the only external script that I'm
loading here is the +1 button.
And that's really just out of expediency because the plus
sign-in button is just a really easy way to add OAuth
support to an application.
But if I didn't want to have any dependencies, we can
certainly just implement that function ourselves.
It's quite easy to do.
The rest of the code is pretty simple.
We'll just start with just the drag and drop.
We add some drag overs and drop targets.
Handle the file selection.
And then we have this media uploader.
This is just a small helper class that I wrote to show how
to do this.
And we're going to do a simple upload and show the results.
So pretty straightforward in terms of just how the app
itself works.
Of course, the interesting part is what happens in that
media uploader function itself and the upload simple.
And before I show that, the reason why this is so
important really comes down two things.
So one, there's just a lot of people out there who just
really prefer to write vanilla JavaScript.
And they don't want to have too many dependencies on
libraries, particularly the Google APIs, which they have
their own script loader, it does some dynamic loading to
actually get the client.
It can make testing a little bit more difficult when you
have those kind of runtime dependencies for
loading your scripts.
The other issue is when you're doing things like a Chrome
packaged app, you have very strict content security
policy, which actually prevents you from including
external resources.
All the scripts need to be packaged as part of the
application itself, which makes using things like the
Google API client problematic.
There are ways around it in terms of sandboxing content
and then using a post message to communicate in between your
application and the sandboxed frames.
But that's a lot of overhead that you have to go through,
both from development and also just in terms of how your app
functions and how easy it is to debug.
It's just a lot of work.
So the nice thing of having CORS Support for upload now is
if you are building something like a Chrome packaged app,
you can use vanilla JavaScript.
You can use the APIs that are built in and fully supported
in that environment to work with the Drive API.
So let's actually take a look at this upload simple.
Let me just scroll up here.
You have a couple different implementations of upload that
we'll talk about.
But this first one is pretty straighforward.
What we're is we're using the file APIs that are now part of
most modern browsers.
And we use that to read the file that we dragged on there.
We just read it as an array buffer.
So it could be binary content.
It really doesn't make a difference.
And then to upload it, we just use XML HTTP request.
It's a post to the Drive upload endpoint.
It's a little bit different than the normal RESTful
endpoint, which is /drive/v2/files.
In this case, we just prefix that with /upload.
Tell it that we're doing media.
Media just indicates that we're just posting the raw
file itself.
We're not giving it any metadata.
And we're not specifying titles or anything.
It's just here's the bytes for the file.
And of course, set the content type appropriately.
But other than that this is vanilla JavaScript.
Again, no external libraries.
Just using the features that are built into the browser in
order to do this.
And we saw on the demo that that worked fine.
Of course, the problem with media is you don't really get
to specify that much control over how the file is
represented in Drive.
You certainly could, once the upload is complete, take the
ID of that file and update the metadata.
It's not quite as efficient as just giving us the metadata
and the file up front.
And to do that, we have a different upload protocol
called multipart.
And we'll actually just do a quick demo of that.
I'm going to scroll over to here.
I'll say upload multipart.
I'm going reload this page.
I did set my approval prompt to [? force, ?] which is why
this button keeps showing up.
But normally, you would just get signed in automatically.
And then this time let's drag a PDF over.
So again, it works.
But you notice this time, we actually
have the correct title.
You can see it here in the metadata returned.
And if we switch over to Drive, we see we actually have
the correct title here as well.
So let's switch back over to the implementation for that.
So again, we have this upload multipart method, which is a
little bit different than our upload simple.
And here we have to do a little bit of work.
We have to actually be able to assemble the multipart body.
So for those who are familiar with doing multipart uploads,
this is going to be familiar.
If you're not, don't worry too much.
It's actually not that difficult.
But basically, we just create a boundary to indicate the
different parts.
We create some metadata.
In this case, the file API in the browser actually gives us
access to the title and the MIME type that the operating
system, or the browser, detects.
And we use that to populate the metadata that we give to
the Drive API.
In this case, we really only care about those two fields,
title and MIME type.
And then again, just like before, we read the file.
Except this time, rather than just posting the raw bytes of
the file, we're actually going to build up
this multipart body.
And the nice thing is, if you looked at the QuickStart that
we've had in our Docs for JavaScript, this
code may look familiar.
In fact, we've had, using the Java API client and some
tricks it uses with iFrame proxies, you actually have
been able to do uploads from JavaScript.
But again, it's been subject to some restrictions in terms
of requiring our script, not quite being incompatible with
packaged app CSP.
But the code for building the multipart is actually already
in that QuickStart.
And so I took that and modified it a little bit just
to make it a little bit cleaner and take advantage of
some of the features that we can now do by exploiting APIs
in modern browsers.
Specifically, building up [INAUDIBLE].
So we can actually, rather than just doing a giant string
concatenation, we could actually just give an array of
all the different parts.
In this case, it's the delimiters, content tapes, the
metadata for the file, which is just a stringify JSON.
And then, our next section, which is the file.
And one nice thing is that when we do this, we can
actually mix content.
So we can mix text, and we can mix binary.
So whereas in the QuickStart example we were forced to do
base-64-encoding of the content in order to be
compatible with how the JavaScript client worked, in
this case, we could actually just use the raw binary.
It saves us a little bit of bandwidth in terms of how the
file is sent over the wire.
It's also a little bit less processing, because we don't
have to do anything with the content itself.
We can just assemble this part, give it the raw binary,
along with the correct content type, and send that.
Other than actually how the body is formatted, the rest of
the code is the same as we did with the media upload, which
is we do a post to the upload endpoint.
The difference is we do multipart instead of media.
We also change the content type to indicate that this is
a multipart request.
Tell it the boundary.
And send the body.
And of course, the onComplete and onError are just call
backs to let us know when that request is done.
And that's where we're updating the
UI to show the media.
There's a third upload protocol, which is actually
really interesting, and the preferred
way for doing uploads.
And it's called resumable uploads.
Unfortunately, I didn't quite get around to writing all the
code for it.
But I do promise that I will clean up the examples that we
have in here today.
We'll add them to the GitHub repository on Google Drive.
And we'll show you how to do all three variants of uploads
in JavaScript.
And hopefully make the code pretty reusable, so you can
just take that into your app and use it yourself or adapt
it to your needs.
But you can get a little bit of a flavor for it here in
some commented out code.
It's very similar to multipart in that you supply both the
metadata for the file, as well as the content itself.
It's just that you actually do this across several requests.
So in the first request, we do a post with
upload type as resumable.
But the content type, in this case, is just the metadata.
It's just JSON with the body.
And we give it a couple of little bits of extra
information via headers, just to tell it about the content
that we're going to upload, what its type is, and what the
expected file size is.
And that's via these upload headers.
And once we do that, we're going to get a redirect to
just a ephemeral URL, which represents our upload session.
Again, this is the part that I haven't quite gotten around to
implementing.
But then once we do that, we can start to
upload the file in chunks.
The preferred approach, when doing resumable uploads, is to
actually try and upload the entire file at once and then
resume if the connection fails.
In the case of a browser, because there are limits on
how much memory you can have, how much of a file you can
actually read into the browser at one point in time, chunking
is actually a good option here.
And so if you wanted to say, for example, implement video
upload in your application to Drive where you have a video
that could be several gigabytes large that you might
be uploading from a desktop, it's probably something that
you're going to want chunk into smaller bits.
And you can do any size chunk.
The minimum is 256K.
But any multiple of that is fine.
So you can do whatever it is, two megabytes
at a time per chunk.
And then just incrementally upload.
And the nice thing is if it fails, or somebody's on their
laptop and they lose their internet
connection, it's fine.
You actually have the course of about 24 hours or so to
actually resume that upload.
And so that actually works really nice for packaged apps.
You're on a Chromebook, and you just happen to be going
around and maybe you're in and out of connectivity.
But you can get that really, really nice upload experience
into your app just using built in browser features.
So again, I'll actually finish this implementation hopefully
later today.
Get that up on GitHub for everyone to take a look at.
And hopefully this is of use.
I know we've seen a lot of interest on this in Stack
Overflow, a lot of questions about how do you do upload in
JavaScript with CORS.
Great news is, starting today, you can do that.
It's actually pretty easy to do.
So that's all I really have for CORS.
For next week, [INAUDIBLE] is going to be in.
And she will be talking about a recent sample that she
posted also on our github.com/googledrive
repositories, which is a really cool cross client
authentication and authorization example that
shows how to do sign in on mobile devices, and have that
identity and your authorization propagate back
to your backend server, so you can use APIs like Drive.
It's really a cool sample.
It's definitely a topic that is a little tricky
to do and get right.
But again, she'll give you a nice walk
through of how that works.
We'll be back with hopefully a new app of the week.
And that's about it.
Again, if you have any questions, come find us on the
Google Drive SDK developers community or Stack
Overflow, of course.
We'd love to get your feedback.
How you're using some of these new features.
And of course, always want to know what you're building.
So that's all for me today.
Thank you very much.
[MUSIC PLAYING]