재개 가능한 업로드

이 페이지에서는 REST 프로토콜을 통해 Google 포토 라이브러리 API에 재개 가능한 업로드를 요청하는 방법을 설명합니다. 이 프로토콜을 사용하면 통신 실패로 데이터 흐름이 중단된 후 업로드 작업을 재개할 수 있습니다.

클라이언트 라이브러리를 사용하는 개발자의 경우 일부 클라이언트 라이브러리가 재개 가능한 업로드를 기본적으로 지원합니다.

다음과 같은 경우 재개 가능한 업로드 옵션을 사용합니다.

  • 대용량 파일을 업로드 중입니다.
  • 네트워크 중단 또는 기타 전송 실패가 발생할 가능성이 높습니다 (예: 모바일 앱에서 파일을 업로드하는 경우).

재개 가능한 업로드는 네트워크 장애 발생 시 대역폭 사용량을 줄일 수 있습니다. 대용량 파일 업로드를 처음부터 다시 시작할 필요가 없기 때문입니다.

1단계: 업로드 세션 시작

https://photoslibrary.googleapis.com/v1/uploads에 POST 요청을 전송하여 재개 가능한 업로드 세션을 시작합니다. 이 요청에서 반환된 재개 가능한 업로드 URL을 사용하여 파일을 업로드합니다.

POST 요청에는 다음 헤더가 포함되어야 합니다.

헤더 필드
Content-Length 요청 본문이 비어 있으므로 0로 설정합니다.
X-Goog-Upload-Command start로 설정합니다.
X-Goog-Upload-Content-Type 파일의 MIME 형식으로 설정합니다(예: image/jpeg).
X-Goog-Upload-Protocol resumable로 설정합니다.
X-Goog-Upload-Raw-Size 전송할 파일 데이터의 총 바이트 수로 설정합니다.

다음은 POST 요청 헤더입니다.

POST https://photoslibrary.googleapis.com/v1/uploads
Authorization: Bearer oauth2-token
Content-Length: 0
X-Goog-Upload-Command: start
X-Goog-Upload-Content-Type: mime-type
X-Goog-Upload-Protocol: resumable
X-Goog-Upload-Raw-Size: bytes-of-file

2단계: 세션 URL 저장

성공하면 POST 요청이 다음 헤더를 포함한 200 OK HTTP 상태 코드를 반환합니다.

X-Goog-Upload-URL: url-to-make-uploads-to
X-Goog-Upload-Chunk-Granularity: chunk-granularity-in-bytes

헤더 필드 x-goog-upload-chunk-granularity에는 클라이언트에서 전송한 모든 데이터 청크의 바이트 정렬 및 크기 세부사항이 포함됩니다. 업로드가 여러 단위로 이루어진 경우 마지막 업로드를 제외한 모든 업로드가 이 값의 배수로 실행되어야 합니다. 즉, 파일의 업로드 바이트를 이 값에 정렬해야 합니다. 마지막 단위에서는 나머지 바이트를 업로드할 수 있습니다.

헤더 필드 X-Goog-Upload-URL에는 나머지 모든 요청을 통해 업로드를 완료하는 데 사용해야 하는 고유한 URL이 포함됩니다. 재개 가능한 세션 URL을 복사하여 이후 요청에 사용할 수 있도록 저장합니다.

3단계: 파일 업로드하기

재개 가능한 세션으로 파일을 업로드하는 방법에는 두 가지가 있습니다.

  1. 단일 요청. 일반적으로 이 접근 방식이 가장 좋습니다. 필요한 요청 수가 적고 결과적으로 성능이 더 우수하기 때문입니다.
  2. 여러 단위. 이 방식에서는 데이터를 청크로 분할하여 여러 요청으로 업로드를 수행합니다. 데이터는 x-goog-upload-chunk-granularity의 배수로 분할됩니다. 필요한 경우 분할된 요청을 다시 시도할 수 있습니다.

    다음과 같은 경우 이 방법을 사용합니다.

    • 단일 요청으로 전송되는 데이터의 양을 줄여야 합니다. 개별 요청에 고정된 시간 제한이 있는 경우 이 작업을 수행해야 할 수 있습니다.
    • 업로드 진행률을 표시하는 맞춤 표시기를 제공해야 합니다.
    • 데이터를 삭제해도 괜찮은 시점을 알아야 합니다.

단일 요청

단일 요청으로 파일을 업로드하는 방법은 다음과 같습니다.

  1. 재개 가능한 세션 URL에 관한 POST 요청을 생성합니다.
  2. 파일의 데이터를 요청 본문에 추가합니다.
  3. 다음 HTTP 헤더를 추가합니다.

    • Content-Length: 파일의 바이트 수로 설정합니다.
    • X-Goog-Upload-Command: upload, finalize로 설정합니다.
  4. 요청을 전송합니다.

업로드 요청이 중단되거나 5xx 응답을 받으면 중단된 업로드 재개 절차를 따릅니다.

요청이 성공하면 응답 본문에 200 OK HTTP 상태 코드와 업로드 토큰이 수신됩니다. 이 업로드 토큰을 사용하여 미디어 항목을 만듭니다.

멀티 청크

파일을 여러 단위로 업로드하려면 다음 단계를 따르세요.

  1. 재개 가능한 세션 URL에 관한 POST 요청을 생성합니다.
  2. 단위의 데이터를 요청 본문에 추가합니다.

    업로드를 완료하는 마지막 단위를 제외하고 허용되는 단위 크기의 배수로 나머지 단위를 만듭니다. 효율적인 업로드를 위해 단위 크기를 최대한 크게 유지하세요.

  3. 다음 HTTP 헤더를 추가합니다.

    • Content-Length: 청크의 바이트 수로 설정합니다.
    • X-Goog-Upload-Command: upload로 설정합니다. 마지막 단위의 경우 upload, finalize로 설정합니다.
    • X-Goog-Upload-Offset: 바이트를 써야 하는 오프셋으로 설정합니다. 바이트는 순차적으로 업로드되어야 합니다. 첫 번째 오프셋은 0입니다.
  4. 요청을 전송합니다.

    업로드 요청이 중단되거나 5xx 응답을 받으면 중단된 업로드 재개 절차를 따릅니다.

  5. 파일의 나머지 단위마다 위 단계를 반복합니다.

요청이 성공하면 응답 본문에 200 OK HTTP 상태 코드와 업로드 토큰이 수신됩니다. 이 업로드 토큰을 사용하여 미디어 항목을 만듭니다.

단일 요청

다음 예는 3,039,417바이트의 JPEG 파일을 단일 요청으로 업로드하기 위한 재개 가능한 요청을 보여줍니다.

POST https://photoslibrary.googleapis.com/v1/uploads HTTP/1.1
Content-Length: 0
X-Goog-Upload-Command: start
X-Goog-Upload-Content-Type: image/jpeg
X-Goog-Upload-Protocol: resumable
X-Goog-Upload-Raw-Size: 3039417
[no body]

응답에는 업로드 URL과 예상 단위 크기가 포함됩니다.

HTTP/1.1 200 OK
X-Goog-Upload-URL: https://photoslibrary.googleapis.com/v1/uploads?upload_id=AEnB2Urq&upload_protocol=resumable
X-Goog-Upload-Chunk-Granularity: 262144

최종 업로드 요청:

POST https://photoslibrary.googleapis.com/v1/uploads?upload_id=AEnB2Urq&upload_protocol=resumable HTTP/1.1
Content-Length: 3039417
X-Goog-Upload-Command: upload, finalize
X-Goog-Upload-Offset: 0

[BYTES 0-4199999]

멀티 청크

다음 예는 재개 가능한 세션 URL과 이전 단계에서 얻은 허용된 단위 크기 세부사항을 사용하여 3,039,417바이트의 JPEG 파일을 여러 단위로 업로드하기 위한 재개 가능한 요청을 보여줍니다. 이 예시에서는 업로드 세션이 초기화될 때 헤더 필드 x-goog-upload-chunk-granularity에 반환된 262,144바이트의 청크 크기를 사용합니다. 각 업로드에는 262,144의 배수인 바이트가 포함됩니다.

이전 단계에서 설명한 대로 업로드 URL과 단위 크기를 수신하도록 업로드 세션을 초기화합니다.

POST https://photoslibrary.googleapis.com/v1/uploads HTTP/1.1
Content-Length: 0
X-Goog-Upload-Command: start
X-Goog-Upload-Content-Type: image/jpeg
X-Goog-Upload-Protocol: resumable
X-Goog-Upload-Raw-Size: 3039417
[no body]

응답에는 업로드 URL과 예상 단위 크기가 포함됩니다.

HTTP/1.1 200 OK
X-Goog-Upload-URL: https://photoslibrary.googleapis.com/v1/uploads?upload_id=AEnB2Urq&upload_protocol=resumable
X-Goog-Upload-Chunk-Granularity: 262144

첫 번째 청크:

POST https://photoslibrary.googleapis.com/v1/uploads?upload_id=AEnB2Urq&upload_protocol=resumable HTTP/1.1
Content-Length: 1048576
X-Goog-Upload-Command: upload
X-Goog-Upload-Offset: 0

[BYTES 0-1048575]

두 번째 청크:

POST https://photoslibrary.googleapis.com/v1/uploads?upload_id=AEnB2Urq&upload_protocol=resumable HTTP/1.1
Content-Length: 1048576
X-Goog-Upload-Command: upload
X-Goog-Upload-Offset: 1048576

[BYTES 1048576-2097151]

마지막 청크:

POST https://photoslibrary.googleapis.com/v1/uploads?upload_id=AEnB2Urq&upload_protocol=resumable HTTP/1.1
Content-Length: 942265
X-Goog-Upload-Command: upload, finalize
X-Goog-Upload-Offset: 2097152

[BYTES 2097152-4200000]

중단된 업로드 재개

업로드 요청이 중단되거나 200가 아닌 HTTP 상태 코드를 수신하면 서버에 쿼리하여 성공한 업로드 양을 확인합니다.

다음은 재개 가능한 세션 URL에 대한 POST 요청입니다. X-Goog-Upload-Commandquery로 설정해야 합니다.

POST https://photoslibrary.googleapis.com/v1/uploads?upload_id=AEnB2Urq&upload_protocol=resumable HTTP/1.1
Content-Length: 0
X-Goog-Upload-Command: query

서버 응답에는 200 OK HTTP 상태 코드와 현재 업로드 크기가 포함됩니다.

HTTP/1.1 200 OK
X-Goog-Upload-Status: active
X-Goog-Upload-Size-Received: 100

그런 다음 이 오프셋에서 업로드를 재개할 수 있습니다. 결합된 업로드 및 완료 명령어를 전송하지 않는 한 서버에서 제공한 오프셋에서 재개해야 합니다. 이 경우 오프셋 0에서 재개할 수도 있습니다.

쿼리 명령어의 HTTP 응답에 X-Goog-Upload-Status 헤더가 있고 값이 active이 아니면 업로드가 이미 종료되었음을 나타냅니다.