L'API Google Play Developer ti consente di caricare immagini, APK o expansionfiles per una modifica. Di seguito utilizziamo le immagini come esempio.
Opzioni di caricamento
L'API Google Play Developer ti consente di caricare determinati tipi di dati binari o contenuti multimediali. Le caratteristiche specifiche dei dati che puoi caricare sono specificate nella pagina di riferimento per qualsiasi metodo che supporta il caricamento di contenuti multimediali:
- Dimensioni massime del file di caricamento: la quantità massima di dati che puoi archiviare con questo metodo.
- Tipi MIME 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 un trasferimento rapido di file più piccoli, ad esempio 5 MB o meno. - Caricamento di più parti:
uploadType=multipart
. Per trasferire rapidamente file e metadati di piccole dimensioni. trasferisce il file insieme ai metadati che lo descrivono, il tutto in un'unica richiesta. - Caricamento ripristinabile:
uploadType=resumable
. Per un trasferimento affidabile, particolarmente importante con file più grandi. Con questo metodo, utilizzi una richiesta di avvio della sessione che, facoltativamente, può includere metadati. Si tratta di una buona strategia da utilizzare per la maggior parte delle applicazioni, dato che funziona anche per 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 è URI della risorsa standard con un prefisso "/upload". Utilizza questo URI quando trasferire i dati multimediali stessi.
Esempio:
POST /upload/androidpublisher/v3/applications/packageName/edits/editId/listings/language/imageType
L'URI della risorsa standard per i metadati. Se la risorsa contiene campi di dati, questi campi vengono utilizzati per archiviare i metadati che descrivono . Puoi utilizzare questo URI durante la creazione o l'aggiornamento dei valori dei metadati.
Esempio:
POST /androidpublisher/v3/applications/packageName/edits/editId/listings/language/imageType
Caricamento semplice
Il metodo più semplice per caricare un file è effettuare una semplice richiesta di caricamento. Questa opzione è una buona scelta se:
- Il file è abbastanza piccolo da poter essere caricato di nuovo integralmente in caso di errore di connessione.
- Nessun metadato da inviare. Questo potrebbe essere vero se prevedi di inviare i metadati per questa risorsa in una richiesta separata o se non sono supportati né disponibili metadati.
Per utilizzare il caricamento semplice, effettua una richiesta POST
o PUT
a
l'URI /upload del metodo e aggiungi il parametro di query
uploadType=media
. Ad esempio:
POST https://www.googleapis.com/upload/androidpublisher/v3/applications/packageName/edits/editId/listings/language/imageType?uploadType=media
Le intestazioni HTTP da utilizzare quando si effettua una semplice richiesta di caricamento includono:
Content-Type
. Imposta uno dei tipi di dati multimediali per il caricamento accettati dal metodo, specificato nel riferimento dell'API.Content-Length
. Imposta il numero di byte che stai caricando. Non è necessario se utilizzi la codifica del trasferimento a blocchi.
Esempio: caricamento semplice
L'esempio seguente mostra l'utilizzo di una semplice richiesta di caricamento per API Google Play Developer.
POST /upload/androidpublisher/v3/applications/packageName/edits/editId/listings/language/imageType?uploadType=media HTTP/1.1 Host: www.googleapis.com Content-Type: image/png Content-Length: number_of_bytes_in_file Authorization: Bearer your_auth_token PNG data
Se la richiesta ha esito positivo, il server restituisce il codice di stato HTTP 200 OK
insieme a tutti i metadati:
HTTP/1.1 200 Content-Type: application/json {
"image": {
"id": string,
"url": string,
"sha1": string
}
}
Caricamento di più parti
Se vuoi inviare metadati relativi ai dati da caricare, puoi effettuare una singola richiesta multipart/related
. Questa è una buona scelta se le dimensioni dei dati che stai inviando sono sufficientemente limitate da essere caricati di nuovo nella loro interezza in caso di interruzione della connessione.
Per utilizzare il caricamento di più parti, 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/androidpublisher/v3/applications/packageName/edits/editId/listings/language/imageType?uploadType=multipart
Le intestazioni HTTP di primo livello da utilizzare quando si effettua una richiesta di caricamento multiparte includono:
Content-Type
. Impostalo su multipart/related e includi la stringa di confine che stai utilizzando per identificare le parti della richiesta.Content-Length
. Impostato sul numero totale di byte nel corpo della richiesta. La parte multimediale della richiesta deve essere inferiore alle dimensioni massime del file specificate per questo metodo.
Il corpo della richiesta è formattato come tipo di contenuto multipart/related
[RFC2387] e contiene esattamente due parti. Le parti sono identificate da una stringa di confine, e la stringa limite finale è seguita da due trattini.
Ogni parte della richiesta con più parti richiede un'intestazione Content-Type
aggiuntiva:
- Parte relativa ai metadati: deve essere visualizzata per prima e
Content-Type
deve corrispondere a uno dei formati di metadati accettati. - Parte multimediale: deve essere seconda e
Content-Type
deve corrispondere a uno dei tipi MIME multimediali accettati dal metodo.
Consulta la documentazione di riferimento dell'API per consultare l'elenco dei tipi MIME multimediali accettati e i limiti di dimensioni per i file caricati relativi a ciascun metodo.
Nota : per creare o aggiornare la parte dei metadati.
Solo, senza caricare i dati associati, invia semplicemente una richiesta POST
o PUT
all'endpoint della risorsa standard:
https://www.googleapis.com/androidpublisher/v3/applications/packageName/edits/editId/listings/language/imageType
Esempio: caricamento di più parti
L'esempio seguente mostra una richiesta di caricamento di più parti per l'API Google Play Developer.
POST /upload/androidpublisher/v3/applications/packageName/edits/editId/listings/language/imageType?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 {
"image": {
"id": string,
"url": string,
"sha1": string
}
} --foo_bar_baz Content-Type: image/png PNG data --foo_bar_baz--
Se la richiesta ha esito positivo, il server restituisce il codice di stato HTTP 200 OK
insieme a tutti i metadati:
HTTP/1.1 200 Content-Type: application/json {
"image": {
"id": string,
"url": string,
"sha1": string
}
}
Caricamento ripristinabile
Per caricare i file di dati in modo più affidabile, puoi utilizzare il protocollo di caricamento ripristinabile. Questo protocollo consente di riprendere un'operazione di caricamento dopo che un errore di comunicazione ha interrotto il flusso di dati. È particolarmente utile se devi trasferire file di grandi dimensioni e la probabilità che si verifichino interruzioni di rete o altri errori di trasmissione è elevata, ad esempio durante il caricamento da un'app client mobile. Inoltre, consente di ridurre l'utilizzo della larghezza di banda in caso di errori di rete, in quanto non è necessario riavviare il caricamento 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 include gli eventuali metadati.
- Salva l'URI della sessione ripristinabile. Salva l'URI della sessione restituito nella risposta della richiesta iniziale. e la utilizzerai per le richieste rimanenti di questa sessione.
- Carica il file. Invia il file multimediale all'URI della sessione ripristinabile.
Inoltre, le app che utilizzano il caricamento ripristinabile devono disporre di codice per riprendere un caricamento interrotto. Se un caricamento viene interrotto, verifica la quantità di dati ricevuti, quindi riprendi il caricamento a partire da quel momento.
Nota : l'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/androidpublisher/v3/applications/packageName/edits/editId/listings/language/imageType?uploadType=resumable
Per questa richiesta di avvio, il corpo è vuoto o contiene solo i metadati. trasferirai i contenuti effettivi del file da caricare nelle richieste successive.
Utilizza le seguenti intestazioni HTTP con la richiesta iniziale:X-Upload-Content-Type
. Imposta il tipo MIME multimediale dei dati di caricamento da trasferire nelle richieste successive.X-Upload-Content-Length
. Imposta il 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 i metadati:
Content-Type
. Impostato in base al tipo di dati dei metadati. Content-Length
. Imposta il numero di byte fornito nel corpo di questa richiesta iniziale. Non è necessario se utilizzi la codifica del trasferimento a blocchi.
Consulta la documentazione di riferimento dell'API per consultare l'elenco dei tipi MIME multimediali accettati e i limiti di dimensioni per i file caricati relativi a ciascun metodo.
Esempio: richiesta di avvio sessione ripristinabile
L'esempio seguente mostra come avviare una sessione ripristinabile per l'API Google Play Developer.
POST /upload/androidpublisher/v3/applications/packageName/edits/editId/listings/language/imageType?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: image/png X-Upload-Content-Length: 2000000 {
"image": {
"id": string,
"url": string,
"sha1": string
}
}
Nota : per una richiesta di aggiornamento iniziale ripristinabile 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/androidpublisher/v3/applications/packageName/edits/editId/listings/language/imageType?uploadType=resumable&upload_id=xa298sd_sdlkj2 Content-Length: 0
Il valore dell'intestazione Location
, come mostrato nell'esempio di risposta riportato sopra, è l'URI di 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 ottenuto nel passaggio precedente. Il formato della richiesta di caricamento è:
PUT session_uri
Le intestazioni HTTP da utilizzare quando si effettuano le richieste di caricamento di file ripristinabili include Content-Length
. Imposta questo elemento sul numero di byte che carichi in questa richiesta, che in genere corrisponde alle dimensioni del file di caricamento.
Esempio: richiesta di caricamento file ripristinabile
Ecco una richiesta ripristinabile per caricare l'intero file PNG da 2.000.000 di byte per l'esempio corrente.
PUT https://www.googleapis.com/upload/androidpublisher/v3/applications/packageName/edits/editId/listings/language/imageType?uploadType=resumable&upload_id=xa298sd_sdlkj2 HTTP/1.1 Content-Length: 2000000 Content-Type: image/png bytes 0-1999999
Se la richiesta ha esito positivo, il server risponde con un HTTP 201 Created
e con tutti i metadati associati alla risorsa. Se la richiesta iniziale della sessione ripristinabile era un PUT
, per aggiornare una risorsa esistente, la risposta positiva sarebbe 200 OK
, insieme a tutti i metadati associati a questa risorsa.
Se la richiesta di caricamento viene interrotta o se ricevi un'HTTP 503 Service Unavailable
o un'altra risposta 5xx
dal server, segui la procedura descritta nella sezione Riprendi un caricamento interrotto.
Caricamento del file in 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 perché alle richieste aggiuntive sono associati dei costi di prestazioni e in genere non è necessario. Tuttavia, potresti dover utilizzare il chunking per ridurre la quantità di dati trasferiti in ogni singola richiesta. Ciò è utile se esiste un limite di tempo fisso per le singole richieste, come accade per alcune classi di richieste di Google App Engine. Consente inoltre di fornire indicazioni di avanzamento del caricamento per i browser precedenti che per impostazione predefinita non supportano lo stato di avanzamento del caricamento.
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:
- Stato della richiesta. Esegui una query sullo stato attuale del caricamento inviando una richiesta
PUT
vuota all'URI del caricamento. Per questa richiesta, le intestazioni HTTP devono includere un'intestazioneContent-Range
che indica che la posizione corrente nel file è sconosciuta. Ad esempio, impostaContent-Range
su*/2000000
se la lunghezza totale del file è 2.000.000. Se non conosci la dimensione originale del file, impostaContent-Range
su*/*
.Nota: puoi richiedere lo stato tra i blocchi, non solo se il caricamento viene interrotto. Questa opzione è utile, ad esempio, se vuoi mostrare le indicazioni di avanzamento del caricamento per i browser precedenti.
- Ottieni il numero di byte caricati. Elabora la risposta della query sullo stato. Il server utilizza l'intestazione
Range
nella risposta per specificare i byte ricevuti fino a quel momento. Ad esempio, un'intestazioneRange
di0-299999
indica che sono stati ricevuti i primi 300.000 byte del file. - Carica i dati rimanenti. Infine, ora che sai dove riprendere la richiesta, invia i dati rimanenti o il blocco attuale. Tieni presente che in entrambi i casi devi trattare i dati rimanenti come un blocco separato, quindi devi inviare l'intestazione
Content-Range
quando 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 attuale nel file da 2.000.000 di byte è sconosciuta.
PUT {session_uri} HTTP/1.1 Content-Length: 0 Content-Range: bytes */2000000
2) Estrai il numero di byte caricati finora dalla risposta.
La risposta del server utilizza l'intestazione Range
per indicare che ha ricevuto finora 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: se il caricamento è completo, è possibile che la risposta relativa allo stato sia 201 Created
o 200 OK
. Questo può accadere se la connessione si interrompeva dopo aver caricato 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-1999999
Best 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 eventuali errori di
5xx
, tra cui:500 Internal Server Error
502 Bad Gateway
503 Service Unavailable
504 Gateway Timeout
- Utilizza una strategia di backoff esponenziale se viene restituito un errore del server
5xx
quando riprendi o ritentano le richieste di caricamento. Questi errori possono verificarsi se un server viene sovraccarico. Il backoff esponenziale può aiutare ad alleviare questo tipo di problemi durante i periodi di volume elevato di richieste o traffico di rete intenso. - Altri tipi di richieste non devono essere gestiti dal backoff esponenziale, ma puoi comunque provarne diversi. Quando riprovi a queste richieste, limita il numero di nuovi tentativi. Ad esempio, prima di segnalare un errore, il codice potrebbe limitare i tentativi a massimo dieci nuovi tentativi.
- Gestisci gli errori
404 Not Found
e410 Gone
quando esegui caricamenti ripristinabili, ripristinando l'intero caricamento dall'inizio.
Backoff esponenziale
Il backoff esponenziale è una strategia di gestione degli errori standard per le applicazioni di rete in cui il client ritenta periodicamente una richiesta non riuscita in un intervallo di tempo sempre più lungo. Se un volume elevato di richieste o un elevato traffico di rete causa la restituzione di errori da parte del server, il backoff esponenziale può essere una buona strategia per gestire questi errori. Al contrario, non si tratta di una strategia pertinente per la gestione di errori non correlati al volume di rete o ai tempi di risposta, quali credenziali di autorizzazione non valide o errori 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 l'implementazione del 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_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_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_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_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_millisecondi e riprova a inviare la richiesta.
- Interrompi. Segnala o registra un errore.
Nel flusso precedente, numero_casuale_millisecondi è un numero casuale di millisecondi inferiore o uguale a 1000. Ciò è necessario, poiché l'introduzione di un piccolo ritardo casuale consente di distribuire il carico in modo più uniforme ed evitare la possibilità di calpestare il server. Il valore di random_number_milliseconds deve essere ridefinito dopo ogni attesa.
Nota : l'attesa è sempre (2 ^ n) + numero_casuale_millisecondi, dove n è un numero intero monotonico crescente 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 determina un ritardo totale di circa 32 secondi prima che una richiesta venga considerata "un errore irreversibile". È consentito un numero massimo maggiore di nuovi tentativi, soprattutto se è in corso un caricamento di lunga durata. assicurati di limitare il ritardo dei nuovi tentativi a un valore ragionevole, ad esempio inferiore a un minuto.