L'API Gmail consente di caricare i dati dei file durante la creazione o l'aggiornamento di una bozza o l'inserimento o l'invio di un messaggio.
Opzioni di caricamento
L'API Gmail consente di caricare determinati tipi di dati binari o contenuti multimediali. Le caratteristiche specifiche dei dati che puoi caricare sono indicate nella pagina di riferimento per qualsiasi metodo che supporti i caricamenti di contenuti multimediali:
- Dimensione massima del file di caricamento: la quantità massima di dati che puoi archiviare con questo metodo.
- Tipi MIME dei contenuti multimediali accettati: i tipi di dati binari che puoi archiviare utilizzando questo metodo.
Puoi effettuare richieste di caricamento in uno dei seguenti modi. Specifica il metodo che stai utilizzando con il parametro di richiesta uploadType.
- Caricamento semplice:
uploadType=media. Per il trasferimento rapido di file più piccoli, ad esempio 5 MB o meno. - Caricamento multiparte:
uploadType=multipart. Per il trasferimento rapido di file e metadati più piccoli; trasferisce il file insieme ai metadati che lo descrivono, tutto in un'unica richiesta. - Caricamento ripristinabile:
uploadType=resumable. Per un trasferimento affidabile, particolarmente importante per i file di grandi dimensioni. Con questo metodo, utilizzi una richiesta di avvio della sessione, che può includere facoltativamente i metadati. Questa è una buona strategia da utilizzare per la maggior parte delle applicazioni, poiché funziona anche per i file più piccoli al costo di una richiesta HTTP aggiuntiva per caricamento.
Quando carichi contenuti multimediali, utilizzi un URI speciale. Infatti, i metodi che supportano i caricamenti di contenuti multimediali hanno due endpoint URI:
L'URI /upload, per i contenuti multimediali. Il formato dell'endpoint di caricamento è l' URI della risorsa standard con un prefisso "/upload". Utilizza questo URI quando trasferisci i dati dei contenuti multimediali stessi.
Esempio:
POST /upload/gmail/v1/users/userId/messages/sendL'URI della risorsa standard, per i metadati. Se la risorsa contiene campi di dati, questi campi vengono utilizzati per archiviare i metadati che descrivono il file caricato. Puoi utilizzare questo URI quando crei o aggiorni i valori dei metadati.
Esempio:
POST /gmail/v1/users/userId/messages/send
Caricamento semplice
Il metodo più semplice per caricare un file è effettuare una richiesta di caricamento semplice. Questa opzione è una buona scelta quando:
- Il file è abbastanza piccolo da poter essere caricato di nuovo nella sua interezza in caso di errore di connessione.
- Non ci sono metadati da inviare. Questo potrebbe essere vero se prevedi di inviare i metadati per questa risorsa in una richiesta separata o se non sono supportati o disponibili metadati.
Per utilizzare il caricamento semplice, effettua una richiesta POST o PUT all'URI /upload del metodo e aggiungi il parametro di query uploadType=media. Ad esempio:
POST https://www.googleapis.com/upload/gmail/v1/users/userId/messages/send?uploadType=media
Le intestazioni HTTP da utilizzare quando effettui una richiesta di caricamento semplice includono:
Content-Type. Imposta su uno dei tipi di dati multimediali di caricamento accettati dal metodo, specificati nel riferimento API .Content-Length. Imposta sul numero di byte che stai caricando. Non è obbligatorio se utilizzi la codifica di trasferimento a blocchi.
Esempio: caricamento semplice
L'esempio seguente mostra l'utilizzo di una richiesta di caricamento semplice per l'API Gmail.
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
Se la richiesta ha esito positivo, il server restituisce il codice di stato HTTP 200 OK insieme a eventuali metadati:
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
}
Caricamento multiparte
Se hai metadati che vuoi inviare insieme ai dati da caricare, puoi effettuare una singola richiesta multipart/related. Questa è una buona scelta se i dati che stai inviando sono abbastanza piccoli da poter essere caricati di nuovo nella loro interezza in caso di errore di connessione.
Per utilizzare il caricamento multiparte, effettua una richiesta POST o PUT all'URI /upload del metodo e aggiungi il parametro di query uploadType=multipart, ad esempio:
POST https://www.googleapis.com/upload/gmail/v1/users/userId/messages/send?uploadType=multipart
Le intestazioni HTTP di primo livello da utilizzare quando effettui una richiesta di caricamento multiparte includono:
Content-Type. Imposta su multipart/related e includi la stringa di limite che utilizzi per identificare le parti della richiesta.Content-Length. Imposta sul numero totale di byte nel corpo della richiesta. La parte multimediale della richiesta deve essere inferiore alla dimensione massima del file specificata per questo metodo.
Il corpo della richiesta è formattato come tipo di contenuti multipart/related [RFC2387] e contiene esattamente due parti. Le parti sono identificate da una stringa di limite e la stringa di limite finale è seguita da due trattini.
Ogni parte della richiesta multiparte richiede un'intestazione Content-Type aggiuntiva:
- Parte dei metadati: deve essere la prima e
Content-Typedeve corrispondere a uno dei formati di metadati accettati. - Parte multimediale: deve essere la seconda e
Content-Typedeve corrispondere a uno dei tipi MIME dei contenuti multimediali accettati dal metodo.
Consulta il riferimento API per l'elenco dei tipi MIME dei contenuti multimediali accettati e i limiti di dimensione per i file caricati di ogni metodo.
Nota: per creare o aggiornare solo la parte dei metadati, senza caricare i dati associati, invia una richiesta POST o PUT all'endpoint della risorsa standard:
https://www.googleapis.com/gmail/v1/users/userId/messages/send
Esempio: caricamento multiparte
L'esempio seguente mostra una richiesta di caricamento multiparte per l'API Gmail.
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--
Se la richiesta ha esito positivo, il server restituisce il codice di stato HTTP 200 OK insieme a eventuali metadati:
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
}
Caricamento ripristinabile
Per caricare i file di dati in modo più affidabile, puoi utilizzare il protocollo di caricamento ripristinabile. Questo protocollo ti consente di riprendere un'operazione di caricamento dopo che un errore di comunicazione ha interrotto il flusso di dati. È particolarmente utile se stai trasferendo file di grandi dimensioni e la probabilità di un'interruzione di rete o di un altro errore di trasmissione è elevata, ad esempio quando carichi da un'app client mobile. Può anche ridurre l'utilizzo della larghezza di banda in caso di errori di rete, perché non devi riavviare i caricamenti di file di grandi dimensioni dall'inizio.
I passaggi per utilizzare il caricamento ripristinabile includono:
- Avvia una sessione ripristinabile. Effettua una richiesta iniziale all'URI di caricamento che includa i metadati, se presenti.
- Salva l'URI della sessione ripristinabile. Salva l'URI della sessione restituito nella risposta alla richiesta iniziale; lo utilizzerai per le richieste rimanenti in questa sessione.
- Carica il file. Invia il file multimediale all'URI della sessione ripristinabile.
Inoltre, le app che utilizzano il caricamento ripristinabile devono avere codice per riprendere un caricamento interrotto. Se un caricamento viene interrotto, scopri quanti dati sono stati ricevuti correttamente e poi riprendi il caricamento da quel punto.
Nota: un URI di caricamento scade dopo una settimana.
Passaggio 1: avvia una sessione ripristinabile
Per avviare un caricamento ripristinabile, effettua una richiesta POST o PUT all'URI /upload del metodo e aggiungi il parametro di query uploadType=resumable, ad esempio:
POST https://www.googleapis.com/upload/gmail/v1/users/userId/messages/send?uploadType=resumable
Per questa richiesta di avvio, il corpo è vuoto o contiene solo i metadati; trasferirai i contenuti effettivi del file che vuoi caricare nelle richieste successive.
Utilizza le seguenti intestazioni HTTP con la richiesta iniziale:X-Upload-Content-Type. Imposta sul tipo MIME dei contenuti multimediali dei dati di caricamento da trasferire nelle richieste successive.X-Upload-Content-Length. Imposta sul numero di byte dei dati di caricamento da trasferire nelle richieste successive. Se la lunghezza non è nota al momento della richiesta, puoi omettere questa intestazione.- Se fornisci metadati:
Content-Type. Imposta in base al tipo di dati dei metadati. Content-Length. Imposta sul numero di byte forniti nel corpo di questa richiesta iniziale. Non è obbligatorio se utilizzi la codifica di trasferimento a blocchi.
Consulta il riferimento API per l'elenco dei tipi MIME dei contenuti multimediali accettati e i limiti di dimensione per i file caricati di ogni metodo.
Esempio: richiesta di avvio della sessione ripristinabile
L'esempio seguente mostra come avviare una sessione ripristinabile per l'API Gmail.
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
}
Nota: Per una richiesta di aggiornamento ripristinabile iniziale senza metadati, lascia vuoto il corpo della richiesta e imposta l'intestazione Content-Length su 0.
La sezione successiva descrive come gestire la risposta.
Passaggio 2: salva l'URI della sessione ripristinabile
Se la richiesta di avvio della sessione ha esito positivo, il server API risponde con un codice di stato HTTP 200 OK. Inoltre, fornisce un'intestazione Location che specifica l'URI della sessione ripristinabile. L'intestazione Location, mostrata nell'esempio seguente, include una parte del parametro di query upload_id che fornisce l'ID di caricamento univoco da utilizzare per questa sessione.
Esempio: risposta di avvio della sessione ripristinabile
Ecco la risposta alla richiesta nel passaggio 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
Il valore dell'intestazione Location, come mostrato nella risposta di esempio riportata sopra, è l'URI della sessione che utilizzerai come endpoint HTTP per eseguire il caricamento effettivo del file o per eseguire query sullo stato del caricamento.
Copia e salva l'URI della sessione in modo da poterlo utilizzare per le richieste successive.
Passaggio 3. Carica il file
Per caricare il file, invia una richiesta PUT all'URI di caricamento che hai ottenuto nel passaggio precedente. Il formato della richiesta di caricamento è:
PUT session_uri
Le intestazioni HTTP da utilizzare quando effettui le richieste di caricamento di file ripristinabili includono Content-Length. Imposta questo valore sul numero di byte che stai caricando in questa richiesta, che in genere è la dimensione del file di caricamento.
Esempio: richiesta di caricamento di file ripristinabili
Ecco una richiesta ripristinabile per caricare l'intero file Email Message di 2.000.000 di byte per l'esempio corrente.
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
Se la richiesta ha esito positivo, il server risponde con un HTTP 201 Created, insieme a eventuali metadati associati a questa risorsa. Se la richiesta iniziale della sessione ripristinabile era una PUT, per aggiornare una risorsa esistente, la risposta di successo sarebbe 200 OK, insieme a eventuali metadati associati a questa risorsa.
Se la richiesta di caricamento viene interrotta o se ricevi una risposta HTTP 503 Service Unavailable o qualsiasi altra risposta 5xx dal server, segui la procedura descritta in Riprendere un caricamento interrotto.
Caricare il file a blocchi
Con i caricamenti ripristinabili, puoi suddividere un file in blocchi e inviare una serie di richieste per caricare ogni blocco in sequenza. Questo non è l'approccio preferito, poiché sono associati costi di prestazioni alle richieste aggiuntive e in genere non è necessario. Tuttavia, potrebbe essere necessario utilizzare la suddivisione in blocchi per ridurre la quantità di dati trasferiti in una singola richiesta. Questa operazione è utile quando è presente un limite di tempo fisso per le singole richieste, come nel caso di determinate classi di richieste di Google App Engine. Ti consente anche di fornire indicazioni sullo stato di avanzamento del caricamento per i browser legacy che non supportano lo stato di avanzamento del caricamento per impostazione predefinita.
Riprendere un caricamento interrotto
Se una richiesta di caricamento viene terminata prima di ricevere una risposta o se ricevi una risposta HTTP 503 Service Unavailable dal server, devi riprendere il caricamento interrotto. Per farlo:
- Stato della richiesta. Esegui una query sullo stato attuale del caricamento inviando una richiesta
PUTvuota all'URI di caricamento. Per questa richiesta, le intestazioni HTTP devono includere un'intestazioneContent-Rangeche indica che la posizione corrente nel file è sconosciuta. Ad esempio, impostaContent-Rangesu*/2000000se la lunghezza totale del file è 2.000.000. Se non conosci la dimensione completa del file, impostaContent-Rangesu*/*.Nota: puoi richiedere lo stato tra i blocchi, non solo se il caricamento viene interrotto. Questa operazione è utile, ad esempio, se vuoi mostrare indicazioni sullo stato di avanzamento del caricamento per i browser legacy.
- Ottieni il numero di byte caricati. Elabora la risposta alla query sullo stato. Il server utilizza l'intestazione
Rangenella risposta per specificare i byte ricevuti finora. Ad esempio, un'intestazioneRangedi0-299999indica che sono stati ricevuti i primi 300.000 byte del file. - Carica i dati rimanenti. Infine, ora che sai da dove riprendere la richiesta, invia i dati rimanenti o il blocco corrente. Tieni presente che devi trattare i dati rimanenti come un blocco separato in entrambi i casi, quindi devi inviare l'intestazione
Content-Rangequando riprendi il caricamento.
Esempio: riprendere un caricamento interrotto
1) Richiedi lo stato del caricamento.
La seguente richiesta utilizza l'intestazione Content-Range per indicare che la posizione corrente nel file di 2.000.000 di byte è sconosciuta.
PUT {session_uri} HTTP/1.1
Content-Length: 0
Content-Range: bytes */20000002) Estrai il numero di byte caricati finora dalla risposta.
La risposta del server utilizza l'intestazione Range per indicare che finora ha ricevuto i primi 43 byte del file. Utilizza il valore superiore dell'intestazione Range per determinare da dove iniziare il caricamento ripreso.
HTTP/1.1 308 Resume Incomplete Content-Length: 0 Range: 0-42
Nota: è possibile che la risposta di stato sia 201 Created o 200 OK se il caricamento è completato. Questo potrebbe accadere se la connessione si è interrotta dopo il caricamento di tutti i byte, ma prima che il client ricevesse una risposta dal server.
3) Riprendi il caricamento dal punto in cui è stato interrotto.
La seguente richiesta riprende il caricamento inviando i byte rimanenti del file, a partire dal byte 43.
PUT {session_uri} HTTP/1.1
Content-Length: 1999957
Content-Range: bytes 43-1999999/2000000
bytes 43-1999999Best practice
Quando carichi contenuti multimediali, è utile conoscere alcune best practice relative alla gestione degli errori.
- Riprendi o riprova i caricamenti non riusciti a causa di interruzioni della connessione o di errori
5xx, tra cui:500 Internal Server Error502 Bad Gateway503 Service Unavailable504 Gateway Timeout
- Utilizza una strategia di backoff esponenziale se viene restituito un errore del server
5xxdurante la ripresa o il nuovo tentativo delle richieste di caricamento. Questi errori possono verificarsi se un server è sovraccarico. Il backoff esponenziale può contribuire ad alleviare questi tipi di problemi durante i periodi di volume elevato di richieste o di traffico di rete intenso. - Altri tipi di richieste non devono essere gestiti dal backoff esponenziale, ma puoi comunque riprovare a eseguirne un certo numero. Quando riprovi a eseguire queste richieste, limita il numero di tentativi. Ad esempio, il codice potrebbe limitare a dieci o meno tentativi prima di segnalare un errore.
- Gestisci gli errori
404 Not Founde410 Gonequando esegui caricamenti ripristinabili avviando l'intero caricamento dall'inizio.
Backoff esponenziale
Il backoff esponenziale è una strategia standard di gestione degli errori per le applicazioni di rete in cui il client riprova periodicamente a eseguire una richiesta non riuscita per un periodo di tempo sempre maggiore. Se un volume elevato di richieste o un traffico di rete intenso fa sì che il server restituisca errori, il backoff esponenziale potrebbe essere una buona strategia per gestire questi errori. Al contrario, non è una strategia pertinente per la gestione degli errori non correlati al volume di rete o ai tempi di risposta, come credenziali di autorizzazione non valide o errori di file non trovato.
Se utilizzato correttamente, il backoff esponenziale aumenta l'efficienza dell'utilizzo della larghezza di banda, riduce il numero di richieste necessarie per ottenere una risposta positiva e massimizza la velocità effettiva delle richieste in ambienti simultanei.
Il flusso per implementare il backoff esponenziale semplice è il seguente:
- Effettua una richiesta all'API.
- Ricevi una risposta
HTTP 503, che indica che devi riprovare a eseguire la richiesta. - Attendi 1 secondo + numero_casuale_di_millisecondi e riprova a eseguire la richiesta.
- Ricevi una risposta
HTTP 503, che indica che devi riprovare a eseguire la richiesta. - Attendi 2 secondi + numero_casuale_di_millisecondi e riprova a eseguire la richiesta.
- Ricevi una risposta
HTTP 503, che indica che devi riprovare a eseguire la richiesta. - Attendi 4 secondi + numero_casuale_di_millisecondi e riprova a eseguire la richiesta.
- Ricevi una risposta
HTTP 503, che indica che devi riprovare a eseguire la richiesta. - Attendi 8 secondi + numero_casuale_di_millisecondi e riprova a eseguire la richiesta.
- Ricevi una risposta
HTTP 503, che indica che devi riprovare a eseguire la richiesta. - Attendi 16 secondi + numero_casuale_di_millisecondi e riprova a eseguire la richiesta.
- Interrompi. Segnala o registra un errore.
Nel flusso precedente, numero_casuale_di_millisecondi è un numero casuale di millisecondi minore o uguale a 1000. Questo è necessario, poiché l'introduzione di un piccolo ritardo casuale contribuisce a distribuire il carico in modo più uniforme ed evitare la possibilità di sovraccaricare il server. Il valore di numero_casuale_di_millisecondi deve essere ridefinito dopo ogni attesa.
Nota: l'attesa è sempre (2 ^ n) + numero_casuale_di_millisecondi, dove n è un numero intero in aumento monotono inizialmente definito come 0. Il numero intero n viene incrementato di 1 per ogni iterazione (ogni richiesta).
L'algoritmo è impostato per terminare quando n è 5. Questo limite impedisce ai client di riprovare all'infinito e comporta un ritardo totale di circa 32 secondi prima che una richiesta venga considerata "un errore non recuperabile". Un numero massimo di tentativi più elevato è accettabile, soprattutto se è in corso un caricamento lungo; assicurati solo di limitare il ritardo dei tentativi a un valore ragionevole, ad esempio inferiore a un minuto.