Interfejs Gmail API umożliwia przesyłanie danych plików podczas tworzenia lub aktualizowania wersji roboczej albo podczas wstawiania lub wysyłania wiadomości.
Opcje przesyłania
Interfejs Gmail API umożliwia przesyłanie określonych typów danych binarnych lub multimediów. Szczegółowe informacje o danych, które możesz przesłać, znajdziesz na stronie referencyjnej dowolnej metody obsługującej przesyłanie multimediów:
- Maksymalny rozmiar przesyłanego pliku: maksymalna ilość danych, jaką możesz przechowywać przy użyciu tej metody.
- Akceptowane typy MIME multimediów: typy danych binarnych, które możesz przechowywać za pomocą tej metody.
Żądania przesyłania możesz wysyłać na jeden z tych sposobów. Określ metodę, której używasz, za pomocą parametru żądania uploadType
.
- Proste przesyłanie:
uploadType=media
. Do szybkiego przesyłania mniejszych plików, np. o rozmiarze 5 MB lub mniejszym. - Przesyłanie wieloczęściowe:
uploadType=multipart
Do szybkiego przesyłania mniejszych plików i metadanych. Przesyła plik wraz z metadanymi, które go opisują, w ramach jednego żądania. - Przesyłanie z możliwością wznowienia:
uploadType=resumable
. Zapewnia niezawodne przesyłanie, co jest szczególnie ważne w przypadku większych plików. W tej metodzie używasz żądania inicjującego sesję, które opcjonalnie może zawierać metadane. Jest to dobra strategia w przypadku większości aplikacji, ponieważ działa też w przypadku mniejszych plików, ale wiąże się z jednym dodatkowym żądaniem HTTP na przesłanie.
Podczas przesyłania multimediów używasz specjalnego identyfikatora URI. Metody obsługujące przesyłanie plików multimedialnych mają 2 punkty końcowe URI:
Identyfikator URI /upload dla multimediów. Format punktu końcowego przesyłania to standardowy identyfikator URI zasobu z prefiksem „/upload”. Użyj tego URI podczas przesyłania samych danych multimedialnych.
Przykład:
POST /upload/gmail/v1/users/userId/messages/send
Standardowy identyfikator URI zasobu dla metadanych. Jeśli zasób zawiera jakiekolwiek pola danych, są one używane do przechowywania metadanych opisujących przesłany plik. Możesz użyć tego identyfikatora URI podczas tworzenia lub aktualizowania wartości metadanych.
Przykład:
POST /gmail/v1/users/userId/messages/send
Proste przesyłanie
Najprostszym sposobem przesyłania pliku jest wysłanie prostego żądania przesłania. Ta opcja jest dobrym wyborem, gdy:
- Jeśli połączenie zostanie przerwane, plik jest wystarczająco mały, aby można go było przesłać ponownie w całości.
- Brak metadanych do wysłania. Może to być prawdą, jeśli planujesz wysłać metadane tego zasobu w osobnym żądaniu lub jeśli metadane nie są obsługiwane lub dostępne.
Aby użyć prostego przesyłania, wyślij żądanie POST
lub PUT
do identyfikatora URI /upload metody i dodaj parametr zapytania uploadType=media
. Na przykład:
POST https://www.googleapis.com/upload/gmail/v1/users/userId/messages/send?uploadType=media
Nagłówki HTTP, które należy użyć podczas wysyłania prostego żądania przesyłania, to:
Content-Type
. Ustaw na jeden z akceptowanych typów danych multimedialnych do przesłania, określonych w dokumentacji interfejsu API.Content-Length
. Ustaw na liczbę przesyłanych bajtów. Nie jest wymagane, jeśli używasz kodowania przesyłania fragmentami.
Przykład: proste przesyłanie
Ten przykład przedstawia użycie prostego żądania przesyłania w interfejsie Gmail API.
POST /upload/gmail/v1/users/userId/messages/send?uploadType=media HTTP/1.1 Host: www.googleapis.com Content-Type: message/rfc822 Content-Length: number_of_bytes_in_file Authorization: Bearer your_auth_token Email Message data
Jeśli żądanie zakończy się powodzeniem, serwer zwróci kod stanu HTTP 200 OK
wraz z metadanymi:
HTTP/1.1 200 Content-Type: application/json {
"id": string,
"threadId": string,
"labelIds": [
string
],
"snippet": string,
"historyId": unsigned long,
"payload": {
"partId": string,
"mimeType": string,
"filename": string,
"headers": [
{
"name": string,
"value": string
}
],
"body": users.messages.attachments Resource,
"parts": [
(MessagePart)
]
},
"sizeEstimate": integer,
"raw": bytes
}
Przesyłanie wieloczęściowe
Jeśli masz metadane, które chcesz wysłać wraz z danymi do przesłania, możesz wysłać pojedynczą prośbę multipart/related
. To dobry wybór, jeśli przesyłane dane są wystarczająco małe, aby w przypadku awarii połączenia można było ponownie przesłać je w całości.
Aby użyć przesyłania wieloczęściowego, wyślij żądanie POST
lub PUT
do identyfikatora URI /upload metody i dodaj parametr zapytania uploadType=multipart
, na przykład:
POST https://www.googleapis.com/upload/gmail/v1/users/userId/messages/send?uploadType=multipart
Nagłówki HTTP najwyższego poziomu, które należy użyć podczas wysyłania żądania przesyłania wieloczęściowego, to:
Content-Type
. Ustaw wartość multipart/related i dołącz ciąg znaków granicznych, którego używasz do identyfikowania części żądania.Content-Length
. Ustaw na łączną liczbę bajtów w treści żądania. Część żądania dotycząca multimediów musi być mniejsza niż maksymalny rozmiar pliku określony dla tej metody.
Treść żądania jest sformatowana jako typ treści multipart/related
[RFC2387] i zawiera dokładnie 2 części. Poszczególne części są identyfikowane za pomocą ciągu ograniczającego, a po ostatnim ciągu ograniczającym znajdują się dwa łączniki.
Każda część żądania wieloczęściowego wymaga dodatkowego nagłówka Content-Type
:
- Część metadanych: musi być pierwsza, a
Content-Type
musi być zgodna z jednym z akceptowanych formatów metadanych. - Część multimedialna: musi występować jako druga, a
Content-Type
musi pasować do jednego z akceptowanych typów MIME multimediów w metodzie.
Listę akceptowanych typów MIME multimediów i limitów rozmiaru przesyłanych plików znajdziesz w dokumentacji interfejsu API poszczególnych metod.
Uwaga: aby utworzyć lub zaktualizować tylko część metadanych bez przesyłania powiązanych danych, wyślij żądanie POST
lub PUT
do standardowego punktu końcowego zasobu:https://www.googleapis.com/gmail/v1/users/userId/messages/send
Przykład: przesyłanie wieloczęściowe
Poniższy przykład pokazuje żądanie przesyłania wieloczęściowego w interfejsie Gmail API.
POST /upload/gmail/v1/users/userId/messages/send?uploadType=multipart HTTP/1.1 Host: www.googleapis.com Authorization: Bearer your_auth_token Content-Type: multipart/related; boundary=foo_bar_baz Content-Length: number_of_bytes_in_entire_request_body --foo_bar_baz Content-Type: application/json; charset=UTF-8 {
"id": string,
"threadId": string,
"labelIds": [
string
],
"snippet": string,
"historyId": unsigned long,
"payload": {
"partId": string,
"mimeType": string,
"filename": string,
"headers": [
{
"name": string,
"value": string
}
],
"body": users.messages.attachments Resource,
"parts": [
(MessagePart)
]
},
"sizeEstimate": integer,
"raw": bytes
} --foo_bar_baz Content-Type: message/rfc822 Email Message data --foo_bar_baz--
Jeśli żądanie zakończy się powodzeniem, serwer zwróci kod stanu HTTP 200 OK
wraz z metadanymi:
HTTP/1.1 200 Content-Type: application/json {
"id": string,
"threadId": string,
"labelIds": [
string
],
"snippet": string,
"historyId": unsigned long,
"payload": {
"partId": string,
"mimeType": string,
"filename": string,
"headers": [
{
"name": string,
"value": string
}
],
"body": users.messages.attachments Resource,
"parts": [
(MessagePart)
]
},
"sizeEstimate": integer,
"raw": bytes
}
Przesyłanie z możliwością wznowienia
Aby przesyłać pliki danych w bardziej niezawodny sposób, możesz użyć protokołu przesyłania możliwego do wznowienia. Ten protokół umożliwia wznowienie przesyłania po przerwaniu przepływu danych z powodu problemów z komunikacją. Jest to szczególnie przydatne, jeśli przesyłasz duże pliki i istnieje duże prawdopodobieństwo przerwania sieci lub innej awarii transmisji, na przykład podczas przesyłania z aplikacji klienckiej na urządzeniu mobilnym. Może to również zmniejszyć zużycie przepustowości w przypadku awarii sieci, ponieważ nie musisz ponownie uruchamiać przesyłania dużych plików od początku.
Czynności związane z używaniem przesyłania możliwego do wznowienia:
- Rozpocznij sesję z możliwością wznowienia. Wyślij początkowe żądanie do identyfikatora URI przesyłania, które zawiera metadane (jeśli występują).
- Zapisz identyfikator URI sesji z możliwością wznowienia. Zapisz identyfikator URI sesji zwrócony w odpowiedzi na żądanie początkowe. Będzie on używany w pozostałych żądaniach w tej sesji.
- Prześlij plik. Wyślij plik multimedialny do identyfikatora URI sesji z możliwością wznowienia.
Aplikacje, które korzystają z przesyłania możliwego do wznowienia, muszą też mieć kod umożliwiający wznowienie przerwanego przesyłania. Jeśli przesyłanie zostanie przerwane, sprawdź, ile danych zostało przesłanych, a następnie wznow je od tego miejsca.
Uwaga: adres URI przesyłania wygasa po tygodniu.
Krok 1. Rozpocznij sesję z możliwością wznowienia
Aby rozpocząć przesyłanie z możliwością wznowienia, wyślij żądanie POST
lub PUT
do identyfikatora URI /upload metody i dodaj parametr zapytania uploadType=resumable
, na przykład:
POST https://www.googleapis.com/upload/gmail/v1/users/userId/messages/send?uploadType=resumable
W przypadku tego żądania inicjującego treść jest pusta lub zawiera tylko metadane. Rzeczywistą zawartość pliku, który chcesz przesłać, prześlesz w kolejnych żądaniach.
W przypadku żądania początkowego użyj tych nagłówków HTTP:X-Upload-Content-Type
. Ustaw na typ MIME przesyłanych danych, które mają być przesyłane w kolejnych żądaniach.X-Upload-Content-Length
. Ustaw na liczbę bajtów danych przesyłanych w kolejnych żądaniach. Jeśli w momencie wysyłania żądania długość jest nieznana, możesz pominąć ten nagłówek.- Jeśli podajesz metadane:
Content-Type
. Ustaw zgodnie z typem danych metadanych. Content-Length
. Ustaw na liczbę bajtów podaną w treści tego początkowego żądania. Nie jest wymagane, jeśli używasz kodowania przesyłania fragmentami.
Listę akceptowanych typów MIME multimediów i limitów rozmiaru przesyłanych plików znajdziesz w dokumentacji interfejsu API poszczególnych metod.
Przykład: żądanie rozpoczęcia sesji z możliwością wznowienia
Poniższy przykład pokazuje, jak zainicjować sesję z możliwością wznowienia w przypadku Gmail API.
POST /upload/gmail/v1/users/userId/messages/send?uploadType=resumable HTTP/1.1 Host: www.googleapis.com Authorization: Bearer your_auth_token Content-Length: 38 Content-Type: application/json; charset=UTF-8 X-Upload-Content-Type: message/rfc822 X-Upload-Content-Length: 2000000 {
"id": string,
"threadId": string,
"labelIds": [
string
],
"snippet": string,
"historyId": unsigned long,
"payload": {
"partId": string,
"mimeType": string,
"filename": string,
"headers": [
{
"name": string,
"value": string
}
],
"body": users.messages.attachments Resource,
"parts": [
(MessagePart)
]
},
"sizeEstimate": integer,
"raw": bytes
}
Uwaga: w przypadku początkowego żądania aktualizacji z możliwością wznowienia bez metadanych pozostaw treść żądania pustą i ustaw nagłówek Content-Length
na 0
.
W następnej sekcji opisujemy, jak postępować w przypadku odpowiedzi.
Krok 2. Zapisz adres URI sesji z możliwością wznowienia
Jeśli żądanie rozpoczęcia sesji zakończy się powodzeniem, serwer interfejsu API odpowie kodem stanu HTTP 200 OK
. Dodatkowo zawiera nagłówek Location
, który określa identyfikator URI sesji z możliwością wznowienia. Nagłówek Location
, widoczny w przykładzie poniżej, zawiera część parametru zapytania upload_id
, która podaje niepowtarzalny identyfikator przesyłania do użycia w tej sesji.
Przykład: odpowiedź na rozpoczęcie sesji z możliwością wznowienia
Oto odpowiedź na żądanie z kroku 1:
HTTP/1.1 200 OK Location: https://www.googleapis.com/upload/gmail/v1/users/userId/messages/send?uploadType=resumable&upload_id=xa298sd_sdlkj2 Content-Length: 0
Wartość nagłówka Location
, jak pokazano w przykładzie odpowiedzi powyżej, to identyfikator URI sesji, którego będziesz używać jako punktu końcowego HTTP do przesyłania plików lub sprawdzania stanu przesyłania.
Skopiuj i zapisz identyfikator URI sesji, aby móc go używać w kolejnych żądaniach.
Krok 3: prześlij plik
Aby przesłać plik, wyślij żądanie PUT
do identyfikatora URI przesyłania uzyskanego w poprzednim kroku. Format żądania przesyłania:
PUT session_uri
Nagłówki HTTP, które mają być używane podczas wysyłania żądań przesyłania plików z możliwością wznowienia, obejmują Content-Length
. Ustaw tę wartość na liczbę bajtów przesyłanych w tym żądaniu, która jest zwykle rozmiarem przesyłanego pliku.
Przykład: żądanie przesyłania pliku z możliwością wznowienia
Oto przykładowe żądanie z możliwością wznowienia, które umożliwia przesłanie całego pliku wiadomości e-mail o rozmiarze 2 000 000 bajtów.
PUT https://www.googleapis.com/upload/gmail/v1/users/userId/messages/send?uploadType=resumable&upload_id=xa298sd_sdlkj2 HTTP/1.1 Content-Length: 2000000 Content-Type: message/rfc822 bytes 0-1999999
Jeśli żądanie się powiedzie, serwer odpowie kodem HTTP 201 Created
oraz metadanymi powiązanymi z tym zasobem. Jeśli pierwotne żądanie sesji z możliwością wznowienia było żądaniem PUT
, aby zaktualizować istniejący zasób, odpowiedź o powodzeniu będzie miała postać 200 OK
wraz z metadanymi powiązanymi z tym zasobem.
Jeśli żądanie przesłania zostanie przerwane lub otrzymasz z serwera odpowiedź HTTP 503 Service Unavailable
albo inną odpowiedź 5xx
, postępuj zgodnie z procedurą opisaną w artykule wznawianie przerwanego przesyłania.
Przesyłanie pliku w częściach
Dzięki wznawianemu przesyłaniu możesz podzielić plik na części i wysłać serię żądań, aby przesłać każdą część po kolei. Nie jest to zalecane podejście, ponieważ dodatkowe żądania wiążą się z kosztami związanymi ze skutecznością i zwykle nie są potrzebne. Może jednak być konieczne użycie dzielenia na części, aby zmniejszyć ilość danych przesyłanych w ramach jednego żądania. Jest to przydatne, gdy poszczególne żądania mają stały limit czasu, jak w przypadku niektórych klas żądań Google App Engine. Umożliwia też m.in. wyświetlanie wskaźników postępu przesyłania w starszych przeglądarkach, które domyślnie nie obsługują tej funkcji.
Wznawianie przerwanego przesyłania
Jeśli żądanie przesłania zostanie zakończone przed otrzymaniem odpowiedzi lub jeśli otrzymasz z serwera odpowiedź HTTP 503 Service Unavailable
, musisz wznowić przerwane przesyłanie. Aby to zrobić:
- Stan prośby. Aby sprawdzić bieżący stan przesyłania, wyślij puste żądanie
PUT
do identyfikatora URI przesyłania. W przypadku tego żądania nagłówki HTTP powinny zawierać nagłówekContent-Range
wskazujący, że bieżąca pozycja w pliku jest nieznana. Jeśli na przykład łączna długość pliku wynosi 2 000 000, ustaw wartośćContent-Range
na*/2000000
. Jeśli nie znasz pełnego rozmiaru pliku, ustawContent-Range
na*/*
.Uwaga: możesz poprosić o stan między częściami, a nie tylko wtedy, gdy przesyłanie zostanie przerwane. Jest to przydatne np. wtedy, gdy chcesz wyświetlać wskaźniki postępu przesyłania w starszych przeglądarkach.
- Pobierz liczbę przesłanych bajtów. Przetwarzanie odpowiedzi na zapytanie o stan. Serwer używa w odpowiedzi nagłówka
Range
, aby określić, które bajty zostały dotychczas odebrane. Na przykład nagłówekRange
o wartości0-299999
oznacza, że otrzymano pierwsze 300 000 bajtów pliku. - Prześlij pozostałe dane. Na koniec, gdy już wiesz, gdzie wznowić żądanie, wyślij pozostałe dane lub bieżący fragment. Pamiętaj, że w obu przypadkach pozostałe dane musisz traktować jako oddzielną część, więc po wznowieniu przesyłania musisz wysłać nagłówek
Content-Range
.
Przykład: wznawianie przerwanego przesyłania
1) Poproś o stan przesyłania.
W tym żądaniu użyto nagłówka Content-Range
,aby wskazać,że bieżąca pozycja w pliku o rozmiarze 2 000 000 bajtów jest nieznana.
PUT {session_uri} HTTP/1.1 Content-Length: 0 Content-Range: bytes */2000000
2) Wyodrębnij z odpowiedzi liczbę bajtów przesłanych do tej pory.
Odpowiedź serwera zawiera nagłówek Range
, który wskazuje, że serwer otrzymał dotychczas pierwsze 43 bajty pliku. Użyj górnej wartości nagłówka Range
, aby określić, od którego miejsca rozpocząć wznowione przesyłanie.
HTTP/1.1 308 Resume Incomplete Content-Length: 0 Range: 0-42
Uwaga: jeśli przesyłanie zostało zakończone, stan może być 201 Created
lub 200 OK
. Może się tak zdarzyć, jeśli połączenie zostanie przerwane po przesłaniu wszystkich bajtów, ale przed otrzymaniem przez klienta odpowiedzi z serwera.
3) wznowić przesyłanie od miejsca, w którym zostało przerwane;
Poniższe żądanie wznawia przesyłanie, wysyłając pozostałe bajty pliku, począwszy od bajtu 43.
PUT {session_uri} HTTP/1.1 Content-Length: 1999957 Content-Range: bytes 43-1999999/2000000 bytes 43-1999999
Sprawdzone metody
Podczas przesyłania multimediów warto znać sprawdzone metody związane z obsługą błędów.
- Wznawianie lub ponawianie przesyłania, które nie powiodło się z powodu przerw w połączeniu lub błędów
5xx
, w tym:500 Internal Server Error
502 Bad Gateway
503 Service Unavailable
504 Gateway Timeout
- Jeśli podczas wznawiania lub ponawiania żądań przesyłania zostanie zwrócony jakikolwiek
5xx
błąd serwera, użyj strategii wykładniczego wycofywania. Te błędy mogą wystąpić, jeśli serwer jest przeciążony. Wycofywanie wykładnicze może pomóc w rozwiązaniu tego typu problemów w okresach dużej liczby żądań lub dużego ruchu w sieci. - Inne rodzaje żądań nie powinny być obsługiwane przez wzrastający czas do ponowienia, ale możesz ponawiać niektóre z nich. Podczas ponawiania tych żądań ogranicz liczbę ponownych prób. Na przykład kod może ograniczać liczbę ponownych prób do 10 lub mniej przed zgłoszeniem błędu.
- Obsługa błędów
404 Not Found
i410 Gone
podczas przesyłania z możliwością wznowienia przez rozpoczęcie całego przesyłania od początku.
Wzrastający czas do ponowienia
Wzrastający czas do ponowienia to standardowa strategia obsługi błędów w aplikacjach sieciowych, w której klient okresowo ponawia nieudane żądanie przez coraz dłuższy czas. Jeśli duża liczba żądań lub duże natężenie ruchu w sieci powoduje, że serwer zwraca błędy, dobrym rozwiązaniem może być wycofywanie się z wykładniczym opóźnieniem. Nie jest to natomiast odpowiednia strategia w przypadku błędów niezwiązanych z wielkością ruchu w sieci ani czasem odpowiedzi, takich jak nieprawidłowe dane uwierzytelniające lub błędy „nie znaleziono pliku”.
Prawidłowo użyty algorytm Exponential backoff zwiększa efektywność wykorzystania przepustowości, zmniejsza liczbę żądań potrzebnych do uzyskania odpowiedzi i maksymalizuje przepustowość żądań w środowiskach współbieżnych.
Proces wdrażania prostego wzrastającego czasu do ponowienia wygląda tak:
- Wyślij żądanie do interfejsu API.
- Otrzymasz odpowiedź
HTTP 503
, która oznacza, że należy ponowić żądanie. - Odczekaj 1 sekundę + losową liczbę milisekund i spróbuj jeszcze raz.
- Otrzymasz odpowiedź
HTTP 503
, która oznacza, że należy ponowić żądanie. - Odczekaj 2 sekundy + losowa_liczba_milisekund i spróbuj jeszcze raz.
- Otrzymasz odpowiedź
HTTP 503
, która oznacza, że należy ponowić żądanie. - Odczekaj 4 sekundy + random_number_milliseconds i spróbuj jeszcze raz.
- Otrzymasz odpowiedź
HTTP 503
, która oznacza, że należy ponowić żądanie. - Odczekaj 8 sekund + losowa_liczba_milisekund i spróbuj ponownie.
- Otrzymasz odpowiedź
HTTP 503
, która oznacza, że należy ponowić żądanie. - Zaczekaj 16 sekund + random_number_milliseconds i spróbuj ponownie.
- Zatrzymaj. Zgłoś lub zarejestruj błąd.
W powyższym procesie zmienna random_number_milliseconds to losowa liczba milisekund nie większa niż 1000. Jest to konieczne, ponieważ wprowadzenie niewielkiego losowego opóźnienia pomaga bardziej równomiernie rozłożyć obciążenie i uniknąć możliwości przeciążenia serwera. Wartość random_number_milliseconds musi być ponownie zdefiniowana po każdym oczekiwaniu.
Uwaga: czas oczekiwania jest zawsze równy (2 ^ n) + random_number_milliseconds, gdzie n to rosnąca monotonicznie liczba całkowita, która początkowo wynosi 0. Liczba całkowita n jest zwiększana o 1 w każdej iteracji (każdym żądaniu).
Algorytm ma się zakończyć, gdy n = 5. Ten limit zapobiega nieskończonemu ponawianiu prób przez klientów i powoduje, że całkowite opóźnienie przed uznaniem żądania za „błąd nieodwracalny” wynosi około 32 sekundy. Większa maksymalna liczba ponownych prób jest w porządku, zwłaszcza jeśli trwa długie przesyłanie. Pamiętaj tylko, aby ograniczyć opóźnienie ponowienia do rozsądnej wartości, np. poniżej minuty.