The Blobstore API allows your application to serve data objects, called blobs, that are much larger than the size allowed for objects in the Datastore service. Blobs are useful for serving large files, such as video or image files, and for allowing users to upload large data files. Blobs are created by uploading a file through an HTTP request. Typically, your applications will do this by presenting a form with a file upload field to the user. When the form is submitted, the Blobstore creates a blob from the file's contents and returns an opaque reference to the blob, called a blob key, which you can later use to serve the blob. The application can serve the complete blob value in response to a user request, or it can read the value directly using a streaming file-like interface.
Introducing the Blobstore
App Engine includes the Blobstore service, which allows applications to serve
data objects limited only by the amount of data that can be uploaded or downloaded
over a single HTTP connection. These objects are called Blobstore values, or blobs.
Blobstore values are served as responses from request handlers and are created
as uploads via web forms. Applications do not create blob data directly; instead,
blobs are created indirectly, by a submitted web form or other HTTP POST request.
Blobstore values can be served to the user, or accessed by the application in a
file-like stream, using the Blobstore API.
To prompt a user to upload a Blobstore value, your application presents a web form with a file upload field. The application generates the form's action URL by calling the Blobstore API. The user's browser uploads the file directly to the Blobstore via the generated URL. Blobstore then stores the blob, rewrites the request to contain the blob key, and passes it to a path in your application. A request handler at that path in your application can perform additional form processing.
To serve a blob, your application sets a header on the outgoing response, and App Engine replaces the response with the blob value.
Blobs can't be modified after they're created, though they can be deleted. Each blob has a corresponding blob info record, stored in the datastore, that provides details about the blob, such as its creation time and content type. You can use the blob key to fetch blob info records and query their properties.
Using the Blobstore
Applications can use the Blobstore to accept large files as uploads from users
and to serve those files. Files are called blobs once they're uploaded. Applications
don't access blobs directly by
filename. Instead, applications refer to blobs through the
appengine.BlobKey
type..
The user creates a blob by submitting an HTML form that includes one or more
file input fields. Your application
sets
blobstore.UploadURL
as the destination (action) of this form, passing the function
a URL path of a handler in your application. When the user submits the form,
the user's browser uploads the specified files directly to the Blobstore. The
Blobstore rewrites the user's request and stores the uploaded file data, replacing
the uploaded file data with one or more corresponding blob keys, then passes the
rewritten request to the handler at the URL path you provided to
blobstore.UploadURL
.
This handler can do additional processing based on the blob key. Finally, the handler must return a headers-only, redirect response (301, 302, or 303), typically a browser redirect to another page indicating the status of the blob upload.
The application can read portions of a Blobstore value using a
blobstore.Reader.
Uploading a blob
To create and upload a blob, follow this procedure:
1. Create an upload URL
Call
blobstore.UploadURL
to create an upload URL for the form that the user will fill out,
passing the application path to load when the POST of the form is completed.
2. Create an upload form
The form must include a file upload field, and the form's enctype must be set to
multipart/form-data. When the user submits the form, the POST is handled by the
Blobstore API, which creates the blob. The API also creates an info record for the
blob and stores the record in the Datastore, and passes the rewritten request to
your application on the given path as a blob key.
You must serve the form's page with a Content-Type of text/html; charset=utf-8,
or any filenames with non-ASCII characters will be misinterpreted.
This is the default content type in Go, but you must remember to do this if you set your own Content-Type.
You can't use a global external Application Load Balancer with a Serverless NEG to handle upload requests sent to the /_ah/upload/ URL
returned from the blobstore.create_upload_url call.
Instead, you must route those upload requests directly to the App Engine service. You can do this by using either the appspot.com domain or a custom domain that is mapped directly to the App Engine service.
3. Implement upload handler
In this handler, you can store the blob key with the rest of your application's data model. The blob key itself remains accessible from the blob info entity in the Datastore. Note that after the user submits the form and your handler is called, the blob has already been saved and the blob info added to the Datastore. If your application doesn't want to keep the blob, you should delete the blob immediately to prevent it from becoming orphaned.
When rewriting the user's request, the Blobstore empties the MIME parts of the uploaded files and adds the blob key as a MIME part header. The Blobstore preserves all other form fields and parts, passing them to the upload handler. If you don't specify a content type, the Blobstore will try to infer it from the file extension. If it can't determine a content type, it assigns the content typeapplication/octet-stream to the newly created blob.
Serving a blob
To serve blobs, you must include a blob download handler as a path in your
application.
This handler should pass the blob key for the desired blob to blobstore.Send
. In this example, the blob key is passed to the download
handler as
the URL argument r.FormValue("blobKey").
In practice, the download handler can get the blob
key by any means you choose, such as through another method or user action.
Blobs can be served from any application URL. To serve a blob in your application, you put a special header in the response containing the blob key. App Engine replaces the body of the response with the content of the blob.
Blob byte ranges
The Blobstore supports serving part of a large value instead of the full value
in response to a request. To serve a partial value, include the X-AppEngine-BlobRange
header in the outgoing response. Its value is a standard HTTP byte range. The byte numbering is zero-based. A blank X-AppEngine-BlobRange
instructs the API to ignore the range header and serve the full blob.
Example ranges include:
0-499serves the first 500 bytes of the value (bytes 0 through 499, inclusive).500-999serves 500 bytes starting with the 501st byte.500-serves all bytes starting with the 501st byte to the end of the value.-500serves the last 500 bytes of the value.
If the byte range is valid for the Blobstore value, the Blobstore sends a 206 Partial Content status code and the requested byte range to the client. If the range is not valid for the value,
the Blobstore sends 416 Requested Range Not Satisfiable.
The Blobstore does not support multiple byte ranges in a single request (for example,
100-199,200-299), whether or not they overlap.
Complete sample application
A Go 1.11 demo app is available in GitHub. Note that you need to insert /v2/ in the old Blobstore package name.
Using the Blobstore API with Cloud Storage
You can use the Blobstore API to store blobs in Cloud Storage instead of storing them in Blobstore. You need to set up a bucket as described in the Cloud Storage documentation and specify the bucket and filename in the UploadURLOptions you supply to the UploadURL function.
In your upload handler, you need to process the returned map of returned blobs and explicitly store the Cloud Storage filename needed to retrieve the blob later.
You can also serve Cloud Storage objects using the Blobstore API.
To serve a Cloud Storage object, use BlobKeyForFile to generate the requiredblobkey as described in
Serving a blob.
Quotas and limits
Space used for Blobstore values contributes to the Stored Data (billable) quota. Blob info entities in the Datastore count towards Datastore-related limits. Notice that Cloud Storage is a pay-to-use service; you will be charged according to the Cloud Storage price sheet.
For more information on system-wide safety quotas, see Quotas.
In addition to system-wide safety quotas, the following limits apply specifically to the use of the Blobstore:
- The maximum size of Blobstore data that can be read by the application with one API call is 32 megabytes.
- The maximum number of files that can be uploaded in a single form POST is 500.