This topic describes how to upload objects to a bucket with versioning enabled or suspended.

Simple upload

When you upload an object to a bucket with versioning enabled, OSS automatically adds a unique version ID for the uploaded object, and returns the version ID as the x-oss-version-id field in the response header. In a bucket with versioning suspended, the version ID added to an upload object is null. If you upload an object with the same name as an existing object to a bucket with versioning suspended, the existing object is overwritten to ensure that each object only has one version of which the ID is null.

You can run the following code to simply upload an object:
package main

import (
  "fmt"
  "net/http"
  "os"
  "strings"

  "github.com/aliyun/aliyun-oss-go-sdk/oss"
)

func main() {
  // Creates an OSSClient instance.
  client, err := oss.New("<yourEndpoint>", "<yourAccessKeyId>", "<yourAccessKeySecret>")
  if err != nil {
    fmt.Println("Error:", err)
    os.Exit(-1)
  }

  // Obtains the bucket.
  bucket, err := client.Bucket("<yourBucketName>")
  if err != nil {
    fmt.Println("Error:", err)
    os.Exit(-1)
  }

  var retHeader http.Header
  // Uploads a string. The oss.GetResponseHeader method is used to obtain the returned header.
  err = bucket.PutObject("<yourObjectName>", strings.NewReader("yourObjectValue"), oss.GetResponseHeader(&retHeader))
  if err != nil {
    fmt.Println("Error:", err)
    os.Exit(-1)
  }
  // Prints x-oss-version-id.
  fmt.Println("x-oss-version-id:", oss.GetVersionId(retHeader))
}

For more information about simple upload, see PutObject.

Append upload

In a bucket with versioning enabled or suspended, the AppendObject operation can be performed only on objects of which the current version is an appendable object.
Note
  • When you perform the AppendObject operation on an object of which the current version is an appendable object, OSS does not generate a historical version for the appendable object.
  • When you perform the PutObject or DeleteObject operation on an object of which the current version is an appendable object, OSS stores the appendable object as a historical version and prevents the object from being further appended.
  • You cannot perform the AppendObject operation on objects of which the current version is not an appendable object (such as a normal object or a delete marker).
You can run the following code to append files to an existing object:
package main

import (
  "fmt"
  "os"
  "strings"
  "github.com/aliyun/aliyun-oss-go-sdk/oss"
)

func main() {
  // Creates an OSSClient.
  client, err := oss.New("<yourEndpoint>", "<yourAccessKeyId>", "<yourAccessKeySecret>")
  if err != nil {
    fmt.Println("Error:", err)
    os.Exit(-1)
  }

  // Obtains the bucket.
  bucket, err := client.Bucket("<yourBucketName>")
  if err != nil {
    fmt.Println("Error:", err)
    os.Exit(-1)
  }

  // For the first append operation, the value position is 0 and the returned value is the position for the next append operation. The position for the next operation is the size of the object appended in the last operation.
  var retHeader http.Header
  var nextPos int64 = 0
  nextPos, err = bucket.AppendObject("<yourObjectName>", strings.NewReader("YourObjectAppendValue1"), nextPos,  oss.GetResponseHeader(&retHeader))
  if err != nil {
    fmt.Println("Error:", err)
    os.Exit(-1)
  }
  // Prints x-oss-version-id.
  fmt.Println("x-oss-version-id:", retHeader.Get("x-oss-version-id"))

  // Performs the second append operations. The oss.GetResponseHeader method is used to obtain the returned header.
  nextPos, err = bucket.AppendObject("<yourObjectName>", strings.NewReader("YourObjectAppendValue2"), nextPos,  oss.GetResponseHeader(&retHeader))
  if err != nil {
    fmt.Println("Error:", err)
    os.Exit(-1)
  }
  // Prints x-oss-version-id.
  fmt.Println("x-oss-version-id:", oss.GetVersionId(retHeader))

  // You can append data to an object for multiple times.
}

For more information about append upload, see AppendObject.

Multipart upload

If you call CompleteMultipartUpload to complete the MultipartUpload task for an object in a bucket with versioning enabled or suspended, OSS generates a unique version ID for the object and returns it as the x-oss-version-id field in the response header

You can run the following code to upload an object in the multipart upload method:
package main
import (
    "fmt"
    "os"
    "github.com/aliyun/aliyun-oss-go-sdk/oss"
)
func main() {
    // Creates an OSSClient instance.
    client, err := oss.New("<yourEndpoint>", "<yourAccessKeyId>", "<yourAccessKeySecret>")
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }
    bucketName := "<yourBucketName>"
    objectName := "<yourObjectName>"
    locaFilename := "<yourLocalFilename>"
    // Uses the oss.GetResponseHeader method to obtain the returned header.
    var retHeader http.Header

    // Obtains the bucket.
    bucket, err := client.Bucket(bucketName)
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }
    chunks, err := oss.SplitFileByPartNum(locaFilename, 3)
    fd, err := os.Open(locaFilename)
    defer fd.Close()
    // Step 1: Initializes a multipart upload event.
    imur, err := bucket.InitiateMultipartUpload(objectName)
    // Step 2: Uploads the parts.
    var parts []oss.UploadPart
    for _, chunk := range chunks {
        fd.Seek(chunk.Offset, os.SEEK_SET)
        // Calls UploadPart to upload each part.
        part, err := bucket.UploadPart(imur, fd, chunk.Size, chunk.Number)
        if err != nil {
            fmt.Println("Error:", err)
            os.Exit(-1)
        }
        parts = append(parts, part)
    }
    // Step 3: Completes the multipart upload task.
    cmur, err := bucket.CompleteMultipartUpload(imur, parts, oss.GetResponseHeader(&retHeader))
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }
    fmt.Println("cmur:", cmur)
    // Prints x-oss-version-id.
    fmt.Println("x-oss-version-id:", oss.GetVersionId(retHeader))
}