Interfejs Gmail API umożliwia przesyłanie danych pliku podczas tworzenia lub aktualizowania projektu albo 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 dla każdej metody, która obsługuje przesyłanie multimediów:
- Maksymalny rozmiar pliku do przesłania: maksymalna ilość danych, które możesz przechowywać za pomocą tej metody.
- Akceptowane typy MIME multimediów: typy danych binarnych, które możesz przechowywać za pomocą tej metody.
Możesz wysyłać prośby o przesłanie w jednym z tych sposobów: Określ metodę, której używasz, za pomocą parametru żądania uploadType
.
- Proste przesyłanie:
uploadType=media
. Szybki transfer mniejszych plików, np. mniejszych niż 5 MB. - Przesyłanie w wielu częściach:
uploadType=multipart
. Do szybkiego przesyłania mniejszych plików i metadanych; przesyła plik wraz z opisującymi go metadanymi w ramach jednego żądania. - Przesyłanie z możliwością wznowienia:
uploadType=resumable
. niezawodność przesyłania, 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ż sprawdza się również w przypadku mniejszych plików, a jedynym kosztem jest jedno dodatkowe żądanie HTTP na każde przesłanie.
Podczas 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 przenoszenia samych danych multimedialnych.
Przykład:
POST /upload/gmail/v1/users/userId/messages/send
Standardowy identyfikator URI zasobu dla metadanych. Jeśli zasób zawiera pola danych, służą one do przechowywania metadanych opisujących przesłany plik. Możesz go używać podczas tworzenia lub aktualizowania wartości metadanych.
Przykład:
POST /gmail/v1/users/userId/messages/send
Przesyłanie proste
Najprostszą metodą przesyłania plików jest wysłanie zwykłego żądania przesyłania. Ta opcja jest dobrym wyborem, jeśli:
- Plik jest na tyle mały, że można go przesłać ponownie w całości, jeśli połączenie się nie powiedzie.
- Brak metadanych do wysłania. Może się tak zdarzyć, jeśli planujesz wysłać metadane tego zasobu w osobnym żądaniu lub jeśli metadane nie są obsługiwane lub niedostę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żywać podczas wysyłania prostego żądania przesyłania:
Content-Type
. Ustaw jeden z akceptowanych typów danych multimediów, określonych w dokumentacji interfejsu API.Content-Length
. Ustaw na liczbę bajtów, które przesyłasz. Nie jest wymagane, jeśli używasz kodowania transferu w porcjach.
Przykład: prosty przesyłanie
Ten przykład pokazuje 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ć razem z danymi do przesłania, możesz wysłać pojedyncze żądanie multipart/related
. Jest to dobry wybór, jeśli dane, które wysyłasz, są na tyle małe, że można je ponownie przesłać w całości, jeśli połączenie się nie powiedzie.
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órych należy używać podczas przesyłania żądania przesyłania wieloczęściowego:
Content-Type
. Ustaw na multipart/related i uwzględnij ciąg znaków granicznych, którego używasz do identyfikowania części żądania.Content-Length
. Ustaw na łączną liczbę bajtów w ciele żądania. Część multimedialna żądania 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. Części są identyfikowane przez ciąg znaków granicznych, a po ostatnim ciągu znaków granicy występują 2 łączniki.
Każda część żądania wieloczęściowego musi zawierać dodatkowy nagłówek Content-Type
:
- Część z metadanymi: musi być pierwsza, a
Content-Type
musi odpowiadać jednemu z obsługiwanych formatów metadanych. - Część multimediów: musi być drugą częścią, a
Content-Type
musi pasować do jednego z obsługiwanych przez metodę typów MIME multimediów.
W dokumentacji interfejsu API znajdziesz listę obsługiwanych typów MIME multimediów i limity rozmiarów przesłanych plików dla każdej metody.
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 w częściach
Przykład poniżej pokazuje żądanie przesyłania wieloczęściowego 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 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 operacji przesyłania po przerwaniu przepływu danych z powodu błędu komunikacji. Jest to szczególnie przydatne, jeśli przesyłasz duże pliki i jest duża szansa na przerwanie połączenia lub inny błąd transmisji, na przykład podczas przesyłania z aplikacji mobilnej. Może to też zmniejszyć wykorzystanie przepustowości w przypadku awarii sieci, ponieważ nie musisz ponownie rozpoczynać przesyłania dużych plików od początku.
Aby przesłać pliki za pomocą przesyłania możliwego do wznowienia:
- Rozpocznij sesję z możliwością wznowienia. Prześlij pierwsze żądanie do identyfikatora URI przesyłania, który zawiera metadane (jeśli istnieją).
- Zapisz identyfikator URI sesji, którą można wznowić. 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. Prześlij plik multimedialny do identyfikatora URI sesji z możliwością wznowienia.
Aplikacje korzystające z przesyłania możliwego do wznowienia muszą też zawierać kod umożliwiający wznowienie przerwanego przesyłania. Jeśli przesyłanie zostanie przerwane, sprawdź, ile danych zostało odebranych, a potem wznów przesyłanie od tego miejsca.
Uwaga: identyfikator URI przesyłania wygasa po tygodniu.
Krok 1. Rozpocznij sesję z możliwością wznowienia
Aby rozpocząć wznawialne przesyłanie, wyślij żądanie POST
lub PUT
do identyfikatora URI metody /upload 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. W kolejnych żądaniach przenosisz rzeczywistą zawartość pliku, który chcesz przesłać.
Użyj tych nagłówków HTTP w pierwszym żądaniu:X-Upload-Content-Type
. Ustaw typ MIME danych do przesłania, które mają być przesyłane w kolejnych żądaniach.X-Upload-Content-Length
. Ustaw liczbę bajtów danych do przesłania, które mają być przesyłane w kolejnych żądaniach. Jeśli długość jest nieznana w momencie wysyłania żądania, możesz pominąć ten nagłówek.- Jeśli przesyłasz metadane:
Content-Type
. Ustaw zgodnie z typem danych metadanych. Content-Length
. Ustaw na liczbę bajtów podanych w treści tego początkowego żądania. Nie jest wymagane, jeśli używasz kodowania transferu w porcjach.
W dokumentacji interfejsu API znajdziesz listę obsługiwanych typów MIME multimediów i limity rozmiarów przesłanych plików dla każdej metody.
Przykład: żądanie zainicjowania sesji z możliwością wznowienia
Ten przykład pokazuje, jak zainicjować sesję z możliwością wznowienia w przypadku interfejsu 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ą, a w nagłówku Content-Length
wpisz 0
.
W następnej sekcji znajdziesz informacje o tym, jak postępować w przypadku otrzymania takiej odpowiedzi.
Krok 2. Zapisz identyfikator URI sesji, którą można wznowić
Jeśli żądanie zainicjowania 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
, pokazany w przykładzie poniżej, zawiera część parametru zapytania upload_id
, która zawiera unikalny identyfikator przesyłania do użycia w tej sesji.
Przykład: odpowiedź na inicjowanie 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 faktycznego przesyłania pliku lub sprawdzania stanu przesyłania.
Skopiuj i zapisz identyfikator URI sesji, aby móc go użyć 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órych należy używać podczas przesyłania żądań przesyłania plików z możliwością wznowienia, to Content-Length
. Ustaw tę wartość na liczbę bajtów przesyłanych w tym żądaniu, czyli zazwyczaj rozmiar pliku do przesłania.
Przykład: prośba o przesyłanie plików z możliwością wznowienia procesu
Oto prośba o przesłanie całego pliku e-maila o długości 2 000 000 bajtów, który można wznowić w przypadku bieżącego przykładu.
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 zostało wykonane, serwer odpowiada HTTP 201 Created
wraz z metadanymi powiązanymi z tym zasobem. Jeśli początkowe żądanie sesji z możliwością wznowienia było PUT
, aby zaktualizować istniejący zasób, odpowiedź na żądanie będzie 200 OK
wraz z metadanymi powiązanymi z tym zasobem.
Jeśli żądanie przesyłania zostanie przerwane lub jeśli serwer zwróci odpowiedź HTTP 503 Service Unavailable
lub inną odpowiedź 5xx
, postępuj zgodnie z instrukcjami podanymi w artykule Wznowienie przerwanego przesyłania.
Przesyłanie pliku w kawałkach
Dzięki możliwości wznawiania przesyłania możesz podzielić plik na części i wysłać serię żądań, aby przesyłać każdą część kolejno. Nie jest to preferowane podejście, ponieważ dodatkowe żądania generują koszty związane z wydajnością, a zazwyczaj nie są potrzebne. Może jednak być konieczne podzielenie danych na mniejsze fragmenty, aby zmniejszyć ilość danych przesyłanych w ramach pojedynczego żądania. Jest to przydatne, gdy w przypadku poszczególnych żądań obowiązuje określony limit czasu, jak ma to miejsce w przypadku niektórych klas żądań Google App Engine. Umożliwia też wyświetlanie informacji o postępie przesyłania w starszych przeglądarkach, które nie obsługują domyślnie postępu przesyłania.
Wznawianie przerwanego przesyłania
Jeśli żądanie przesyłania zostało przerwane przed otrzymaniem odpowiedzi lub jeśli serwer zwróci 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
, który wskazuje, że bieżąca pozycja w pliku jest nieznana. Na przykład, jeśli łączna długość pliku wynosi 2 000 000, ustaw wartośćContent-Range
na*/2000000
. Jeśli nie znasz pełnego rozmiaru pliku, ustaw wartośćContent-Range
na*/*
.Uwaga: możesz poprosić o stan między fragmentami, a nie tylko wtedy, gdy przesyłanie zostało przerwane. Jest to przydatne, jeśli chcesz wyświetlać informacje o postępie przesyłania w przypadku starszych przeglądarek.
- Pobierz liczbę przesłanych bajtów. Przetworzenie odpowiedzi na zapytanie o stan. Serwer w odpowiedzi używa nagłówka
Range
, aby określić, które bajty zostały do tej pory odebrane. Na przykład nagłówekRange
o wartości0-299999
wskazuje, że otrzymano pierwsze 300 tys. bajtów pliku. - Prześlij pozostałe dane. Teraz, gdy wiesz, gdzie wznowić żądanie, prześlij pozostałe dane lub bieżący fragment. Pamiętaj, że w obu przypadkach pozostałe dane należy traktować jako oddzielny fragment, więc podczas wznawiania przesyłania należy wysłać nagłówek
Content-Range
.
Przykład: wznawianie przerwanego przesyłania
1) Poproś o stan przesyłania.
W następującym żądaniu nagłówek Content-Range
wskazuje, że bieżąca pozycja w pliku o długości 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ę przesłanych do tej pory bajtów.
Odpowiedź serwera używa nagłówka Range
, aby wskazać, że do tej pory otrzymał pierwsze 43 bajty pliku. Aby określić, od którego miejsca wznowić przesyłanie, użyj górnej wartości nagłówka Range
.
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 zostało zerwane po przesłaniu wszystkich bajtów, ale zanim klient otrzymał odpowiedź od serwera.
3) wznowić przesyłanie od miejsca, w którym zostało przerwane.
Następujące żą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-1999999
Sprawdzone metody
Podczas przesyłania multimediów warto zapoznać się ze sprawdzonymi metodami dotyczącymi obsługi błędów.
- wznowić lub ponownie spróbować przesłać dane, które nie zostały przesłane z powodu przerwania połączenia lub innych błędów
5xx
, w tym:500 Internal Server Error
502 Bad Gateway
503 Service Unavailable
504 Gateway Timeout
- Użyj strategii wykładniczego zmniejszania wartości, jeśli podczas wznawiania lub ponownego próbowania żądań przesyłania zwracany jest jakikolwiek błąd serwera
5xx
. Te błędy mogą wystąpić, jeśli serwer jest przeciążony. Zmniejszanie skoku w czasie może pomóc w rozwiązaniu tego typu problemów w okresach dużego natężenia ruchu w sieci lub dużej liczby żądań. - Inne rodzaje żądań nie powinny być obsługiwane przez wykładniczy czas do ponowienia, ale możesz je powtórzyć. Gdy powtarzasz te żądania, ogranicz liczbę prób. Na przykład Twój kod może ograniczyć liczbę prób do 10 lub mniej, zanim zgłosi błąd.
- Aby rozwiązać problemy z błędami
404 Not Found
i410 Gone
podczas przesyłania z możliwością wznowienia, zacznij przesyłanie od początku.
Wzrastający czas do ponownej próby
Wzrost czasu do ponowienia to standardowa strategia obsługi błędów w przypadku aplikacji sieciowych, w których klient okresowo powtarza nieudane żądanie z coraz dłuższym opóźnieniem. Jeśli duża liczba żądań lub duży ruch w sieci powodują, że serwer zwraca błędy, dobrym sposobem na ich obsługę może być odrzucenie wykładnicze. Nie jest to jednak odpowiednia strategia na radzenie sobie z błędami niezwiązanymi z objętością sieci lub czasem odpowiedzi, np. z błędami nieprawidłowych danych autoryzujących lub nie znaleziono pliku.
Prawidłowo stosowany algorytm sterowania dynamiką zwiększa efektywność wykorzystania przepustowości, zmniejsza liczbę żądań wymaganych do uzyskania odpowiedzi i maksymalizuje przepustowość żądań w środowiskach równoczesnych.
Schemat implementacji prostego wzrastającego czasu do ponowienia:
- Wyślij żądanie do interfejsu API.
- Otrzymasz odpowiedź
HTTP 503
, która wskazuje, że należy ponownie wysłać żądanie. - Zaczekaj 1 sekundę + random_number_milliseconds i ponownie prześlij żądanie.
- Otrzymasz odpowiedź
HTTP 503
, która wskazuje, że należy ponownie wysłać żądanie. - Zaczekaj 2 sekundy + random_number_milliseconds i ponownie prześlij żądanie.
- Otrzymasz odpowiedź
HTTP 503
, która wskazuje, że należy ponownie wysłać żądanie. - Zaczekaj 4 sekundy + random_number_milliseconds i ponownie prześlij żądanie.
- Otrzymasz odpowiedź
HTTP 503
, która wskazuje, że należy ponownie wysłać żądanie. - Zaczekaj 8 sekund + random_number_milliseconds i ponownie prześlij żądanie.
- Otrzymasz odpowiedź
HTTP 503
, która wskazuje, że należy ponownie wysłać żądanie. - Zaczekaj 16 sekund + random_number_milliseconds i ponownie prześlij żądanie.
- Zatrzymaj. zgłaszać lub rejestrować błędy;
W powyższym procesie parametr random_number_milliseconds jest losową liczbą milisekund mniejszą lub równą 1000. Jest to konieczne, ponieważ wprowadzenie niewielkiego opóźnienia losowego pomaga w bardziej równomiernym rozłożeniu obciążenia i unikaniu zablokowania serwera. Po każdym oczekiwaniu należy ponownie zdefiniować wartość parametru random_number_milliseconds.
Uwaga: czas oczekiwania to zawsze (2 ^ n) + random_number_milliseconds, gdzie n to monotonicznie rosnąca liczba całkowita zdefiniowana początkowo jako 0. Liczba całkowita n jest zwiększana o 1 w przypadku każdej iteracji (każdego żądania).
Algorytm jest ustawiony tak, aby zakończyć działanie, gdy n = 5. Ten limit zapobiega nieskończonemu powtarzaniu prób przez klientów i powoduje opóźnienie około 32 sekund, zanim żądanie zostanie uznane za „nieodwracalny błąd”. Większa maksymalna liczba prób jest w porządku, zwłaszcza jeśli trwa długie przesyłanie. Pamiętaj tylko, aby ustawić rozsądny czas oczekiwania na ponowne próby, np. mniej niż minutę.