Interfejs Gmail API umożliwia przesyłanie danych pliku 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żna przesyłać, znajdziesz na stronie referencyjnej każdej metody obsługującej przesyłanie multimediów:
- Maksymalny rozmiar przesyłanego pliku: maksymalna ilość danych, które można przechowywać przy użyciu tej metody.
- Accepted media MIME types (Akceptowane typy MIME multimediów): typy danych binarnych, które możesz przechowywać za pomocą tej metody.
Żądania przesłania możesz wysyłać na dowolny 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 do 5 MB. - 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 niezawodny transfer, co jest szczególnie ważne w przypadku większych plików. W tej metodzie używasz żądania inicjującego sesję, które może opcjonalnie zawierać metadane. Jest to dobra strategia w przypadku większości aplikacji, ponieważ działa również w przypadku mniejszych plików kosztem jednego dodatkowego żądania HTTP na przesłanie.
Do przesyłania multimediów używasz specjalnego identyfikatora URI. Metody obsługujące przesyłanie multimediów 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 identyfikatora URI podczas przesyłania danych multimedialnych.
Przykład:
POST /upload/gmail/v1/users/userId/messages/sendStandardowy identyfikator URI zasobu dla metadanych. Jeśli zasób zawiera 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 przesłania pliku jest wysłanie prostego żądania przesyłania. Ta opcja jest dobrym wyborem, gdy:
- Plik jest na tyle mały, że w razie niepowodzenia połączenia można go przesłać ponownie w całości.
- Brak metadanych do wysłania. Może tak być, 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órych należy użyć podczas wysyłania prostego żądania przesłania, to m.in.:
Content-Type. Ustaw jeden z akceptowanych przez metodę typów danych multimedialnych do przesłania, które są określone w dokumentacji API.Content-Length. Ustaw liczbę bajtów, które przesyłasz. Nie jest wymagany, jeśli używasz kodowania fragmentowanego.
Przykład: proste przesyłanie
Ten przykład przedstawia sposób użycia 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 się powiedzie, 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
}
Operacja przesyłania podzielona na części
Jeśli masz metadane, które chcesz wysłać razem z danymi do przesłania, możesz wysłać pojedyncze żądanie multipart/related. To dobry wybór, jeśli wysyłane dane są na tyle małe, że w razie niepowodzenia połączenia można je przesłać ponownie w całości.
Aby użyć operacji przesyłania podzielonej na części, 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órych należy używać podczas wysyłania żądania przesyłania wieloczęściowego, to m.in.:
Content-Type. Ustaw wartość multipart/related i uwzględnij ciąg graniczny, 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 składa się dokładnie z 2 części. Części są identyfikowane przez ciąg graniczny, a po ostatnim ciągu granicznym następują 2 łączniki.
Każda część żądania wieloczęściowego wymaga dodatkowego nagłówka Content-Type:
- Część z metadanymi: musi znajdować się na początku, a
Content-Typemusi być zgodny z jednym z akceptowanych formatów metadanych. - Treść nagrana: musi być na drugim miejscu, a
Content-Typemusi odpowiadać jednemu z akceptowanych przez metodę typów MIME treści nagranej.
Listę akceptowanych typów MIME multimediów i limity rozmiaru przesyłanych plików dla każdej metody znajdziesz w dokumentacji interfejsu API.
Uwaga: aby utworzyć lub zaktualizować tylko część metadanych bez przesyłania powiązanych danych, wystarczy wysłać żądanie POST lub PUT do standardowego punktu końcowego zasobu:
https://www.googleapis.com/gmail/v1/users/userId/messages/send
Przykład: operacja przesyłania podzielona na części
Poniższy przykład pokazuje żądanie wieloczęściowego przesyłania dla interfejsu 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 się powiedzie, 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 z możliwością wznowienia. Ten protokół umożliwia wznowienie operacji przesyłania po tym, jak błąd komunikacji przerwał przepływ danych. Jest to szczególnie przydatne, gdy przesyłasz duże pliki i istnieje duże prawdopodobieństwo przerwania połączenia sieciowego lub innego błędu transmisji, na przykład podczas przesyłania z aplikacji klienta mobilnego. Może to również zmniejszyć wykorzystanie przepustowości w przypadku awarii sieci, ponieważ nie trzeba ponownie rozpoczynać przesyłania dużych plików od początku.
Aby skorzystać z przesyłania z możliwością wznowienia:
- Rozpocznij sesję z możliwością wznowienia. Wyślij początkowe żądanie do identyfikatora URI przesyłania, który zawiera metadane (jeśli są dostępne).
- Zapisz identyfikator URI sesji z możliwością wznowienia. Zapisz identyfikator URI sesji zwrócony w odpowiedzi na pierwsze żądanie. Będziesz go używać w pozostałych żądaniach w tej sesji.
- Prześlij plik. Wyślij plik multimedialny do identyfikatora URI sesji z możliwością wznowienia.
Dodatkowo aplikacje, które korzystają z przesyłania z możliwością wznowienia, muszą zawierać kod umożliwiający wznowienie przerwanego przesyłania. Jeśli przesyłanie zostanie przerwane, dowiedz się, ile danych zostało pomyślnie odebranych, a następnie wznów przesyłanie od tego momentu.
Uwaga: identyfikator 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 początkowym żądaniu użyj tych nagłówków HTTP:X-Upload-Content-Type. Ustaw typ MIME multimediów przesyłanych danych, które mają zostać przeniesione w kolejnych żądaniach.X-Upload-Content-Length. Ustaw liczbę bajtów danych do przesłania w kolejnych żądaniach. Jeśli długość jest nieznana w momencie wysyłania żądania, możesz pominąć ten nagłówek.- Jeśli podajesz metadane:
Content-Type. Ustaw zgodnie z typem danych metadanych. Content-Length. Ustaw liczbę bajtów podaną w treści tego początkowego żądania. Nie jest wymagany, jeśli używasz kodowania fragmentowanego.
Listę akceptowanych typów MIME multimediów i limity rozmiaru przesyłanych plików dla każdej metody znajdziesz w dokumentacji interfejsu API.
Przykład: żądanie rozpoczęcia sesji z możliwością wznowienia
Poniższy przykład pokazuje, jak zainicjować sesję możliwą do wznowienia w interfejsie 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 opisano, jak postępować z odpowiedzią.
Krok 2. Zapisz identyfikator URI sesji z możliwością wznowienia
Jeśli żądanie rozpoczęcia sesji się powiedzie, serwer interfejsu API odpowie kodem stanu HTTP 200 OK. Dodatkowo zawiera nagłówek Location, który określa identyfikator URI sesji możliwej do wznowienia. Nagłówek Location, pokazany w przykładzie poniżej, zawiera część parametru zapytania upload_id, która podaje unikalny identyfikator przesyłania do użycia w tej sesji.
Przykład: odpowiedź na żądanie rozpoczęcia 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 powyższym przykładzie odpowiedzi, to identyfikator URI sesji, którego użyjesz jako punktu końcowego HTTP do przesłania pliku lub sprawdzenia 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 przesłania:
PUT session_uri
Nagłówki HTTP, których należy używać podczas wysyłania żądań przesyłania plików z możliwością wznowienia, obejmują Content-Length. Ustaw tę wartość na liczbę bajtów, które przesyłasz w tym żądaniu. Zwykle jest to rozmiar przesyłanego pliku.
Przykład: żądanie przesyłania pliku z możliwością wznowienia
Oto żądanie z możliwością wznowienia, które służy do przesłania całego pliku wiadomości e-mail o rozmiarze 2 000 000 bajtów w bieżącym przykładzie.
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 HTTP 201 Created wraz z metadanymi powiązanymi z tym zasobem. Jeśli początkowe żą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 wszelkimi metadanymi powiązanymi z tym zasobem.
Jeśli żądanie przesyłania zostanie przerwane lub otrzymasz z serwera odpowiedź HTTP 503 Service Unavailable lub inną odpowiedź 5xx, postępuj zgodnie z procedurą opisaną w sekcji Wznawianie przerwanego przesyłania.
Przesyłanie pliku we fragmentach
W przypadku przesyłania z możliwością wznowienia możesz podzielić plik na fragmenty i wysłać serię żądań, aby przesłać każdy fragment po kolei. Nie jest to preferowane podejście, ponieważ dodatkowe żądania wiążą się z kosztami związanymi z wydajnością i zwykle nie są potrzebne. Może być jednak konieczne użycie fragmentacji, aby zmniejszyć ilość danych przesyłanych w jednym żądaniu. Jest to przydatne, gdy obowiązuje stały limit czasu dla poszczególnych żądań, 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 przesyłania zostanie przerwane 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. Sprawdź bieżący stan przesyłania, wysyłając puste żądanie
PUTdo identyfikatora URI przesyłania. W przypadku tego żądania nagłówki HTTP powinny zawierać nagłówekContent-Rangewskazujący, że bieżąca pozycja w pliku jest nieznana. Jeśli na przykład łączna długość pliku wynosi 2 000 000, ustaw parametrContent-Rangena*/2000000. Jeśli nie znasz pełnego rozmiaru pliku, ustawContent-Rangena*/*.Uwaga: stan możesz sprawdzać między fragmentami, a nie tylko wtedy, gdy przesyłanie zostanie przerwane. Jest to przydatne, jeśli chcesz na przykład wyświetlać wskaźniki postępu przesyłania w starszych przeglądarkach.
- Pobieranie liczby przesłanych bajtów Przetwórz odpowiedź na zapytanie o stan. Serwer używa nagłówka
Rangew odpowiedzi, aby określić, które bajty zostały już odebrane. Na przykład nagłówekRangeo wartości0-299999wskazuje, że odebrano pierwsze 300 000 bajtów pliku. - Prześlij pozostałe dane. 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 potraktować jako osobny fragment, więc przy wznawianiu przesyłania musisz wysłać nagłówek
Content-Range.
Przykład: wznawianie przerwanego przesyłania
1) Poproś o stan przesyłania.
To żądanie używa 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 */20000002) Wyodrębnij z odpowiedzi liczbę przesłanych do tej pory bajtów.
Odpowiedź serwera zawiera nagłówek Range, który wskazuje, że serwer otrzymał do tej pory pierwsze 43 bajty pliku. Użyj górnej wartości nagłówka Range, aby określić, gdzie 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, odpowiedź dotycząca stanu może mieć wartość 201 Created lub 200 OK. Może się tak zdarzyć, jeśli połączenie zostało przerwane po przesłaniu wszystkich bajtów, ale zanim klient otrzymał odpowiedź z serwera.
3) Wznów przesyłanie od miejsca, w którym zostało przerwane.
To żądanie wznawia przesyłanie, wysyłając pozostałe bajty pliku, zaczynając od bajtu 43.
PUT {session_uri} HTTP/1.1
Content-Length: 1999957
Content-Range: bytes 43-1999999/2000000
bytes 43-1999999Sprawdzone metody
Podczas przesyłania multimediów warto pamiętać o kilku sprawdzonych metodach związanych z obsługą błędów.
- Wznawiać lub ponawiać przesyłanie, które nie powiodło się z powodu przerw w połączeniu lub błędów
5xx, w tym:500 Internal Server Error502 Bad Gateway503 Service Unavailable504 Gateway Timeout
- Jeśli podczas wznawiania lub ponawiania próby przesłania wystąpi błąd serwera
5xx, zastosuj strategię wzrastającego czasu do ponowienia. Te błędy mogą wystąpić, jeśli serwer jest przeciążony. Wzrastający czas do ponowienia 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 nadal możesz ponowić niektóre z nich. Podczas ponownego wysyłania tych żądań ogranicz liczbę prób. Na przykład kod może ograniczać liczbę ponownych prób do 10 lub mniej, zanim zgłosi błąd.
- Obsługuj błędy
404 Not Foundi410 Gonepodczas przesyłania z możliwością wznowienia, rozpoczynając całe przesyłanie 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, zwiększając czas między próbami. Jeśli duża liczba żądań lub duży ruch w sieci powodują, że serwer zwraca błędy, wzrastający czas do ponowienia może być dobrą strategią ich obsługi. Nie jest to jednak odpowiednia strategia w przypadku błędów niezwiązanych z natężeniem ruchu w sieci ani czasem odpowiedzi, takich jak nieprawidłowe dane uwierzytelniające lub błędy braku pliku.
Prawidłowo stosowany wzrastający czas do ponowienia zwiększa efektywność wykorzystania przepustowości, zmniejsza liczbę żądań wymaganych do uzyskania odpowiedzi i maksymalizuje przepustowość żądań w środowiskach równoległych.
Proces implementacji prostego wzrastającego czasu do ponowienia wygląda następująco:
- wysłać żądanie do interfejsu API,
- Otrzymasz odpowiedź
HTTP 503, która wskazuje, że należy ponowić żądanie. - Odczekaj 1 sekundę + losowa_liczba_milisekund i spróbuj jeszcze raz.
- Otrzymasz odpowiedź
HTTP 503, która wskazuje, że należy ponowić żądanie. - Zaczekaj 2 sekundy + losowa_liczba_milisekund i spróbuj jeszcze raz.
- Otrzymasz odpowiedź
HTTP 503, która wskazuje, że należy ponowić żądanie. - Zaczekaj 4 sekundy + losowa_liczba_milisekund i spróbuj jeszcze raz.
- Otrzymasz odpowiedź
HTTP 503, która wskazuje, że należy ponowić żądanie. - Zaczekaj 8 sekund + losowa_liczba_milisekund i spróbuj jeszcze raz.
- Otrzymasz odpowiedź
HTTP 503, która wskazuje, że należy ponowić żądanie. - Odczekaj 16 sekund + losowa_liczba_milisekund i spróbuj jeszcze raz.
- Zatrzymaj. Zgłoś lub zarejestruj błąd.
W powyższym procesie random_number_milliseconds to losowa liczba milisekund mniejsza lub równa 1000. Jest to konieczne, ponieważ wprowadzenie niewielkiego losowego opóźnienia pomaga bardziej równomiernie rozłożyć obciążenie i uniknąć przeciążenia serwera. Wartość random_number_milliseconds musi być ponownie definiowana po każdym oczekiwaniu.
Uwaga: czas oczekiwania zawsze wynosi (2 ^ n) + losowa_liczba_milisekund, gdzie n to monotonicznie rosnąca liczba całkowita, która początkowo jest zdefiniowana jako 0. Liczba całkowita n jest zwiększana o 1 przy każdej iteracji (każdym żądaniu).
Algorytm jest ustawiony tak, aby kończył działanie, gdy n = 5. Ten limit zapobiega nieskończonemu ponawianiu prób przez klientów i powoduje, że łączny czas oczekiwania, zanim żądanie zostanie uznane za „nieodwracalny błąd”, wynosi około 32 sekund. Większa maksymalna liczba ponownych prób jest w porządku, zwłaszcza jeśli trwa długie przesyłanie. Pamiętaj tylko, aby opóźnienie ponownej próby było rozsądne, np. krótsze niż minuta.