How to perform multipart requests in Go
In this article, you’ll learn how to make multipart/related
requests in Go using standard library packages. I’ll demonstrate this concept using the Google Drive API’s multipart upload method for creating files.
A multipart related request is used for compound documents where you would need to combine the separate body parts to provide the full meaning of the message. For example, the Google Drive API provides a multipart upload method for transferring a small file (5 MB or less) and metadata that describes the file, in a single request. The body of the request should contain two parts:
- The file’s metadata in JSON format. It must come first, and its
Content-Type
header must be set toapplication/json; charset=UTF-8
. - The file’s data whose
Content-Type
header is set to the MIME type of the file.
Let’s go ahead and construct the request body using the mime/multipart
and net/textproto
packages.
The next step after creating the body of the request is to create a POST request
to the relevant endpoint, and add the necessary top-level headers which are
Content-Type
and Content-Length
according the Google Drive API
documentation.
func upload() error {
// [..]
accessToken := "<google drive api access token>"
endpoint := "https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart"
req, err := http.NewRequest("POST", endpoint, bytes.NewReader(body.Bytes()))
if err != nil {
return err
}
// Request Content-Type with boundary parameter.
contentType := fmt.Sprintf("multipart/related; boundary=%s", writer.Boundary())
req.Header.Set("Content-Type", contentType)
// Content-Length must be the total number of bytes in the request body.
req.Header.Set("Content-Length", fmt.Sprintf("%d", body.Len()))
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", accessToken))
client := &http.Client{Timeout: 120 * time.Second}
resp, err := client.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
// Do what you want with the response
return nil
}
The complete code can be accessed through this GitHub gist. Thanks for reading, and happy coding!