Download di file
Alcuni endpoint delle API non restituiscono un oggetto JSON con i campi error, message, data e meta, ma restituiscono direttamente un file da scaricare.
È il caso, ad esempio, dei download di fatture e note di credito in formato PDF o XML.
Come riconoscere un endpoint di download
Negli endpoint di download, una risposta 200 OK restituisce direttamente il contenuto binario del file.
In pratica:
- se la richiesta va a buon fine, il body della risposta contiene il file;
- se invece si verifica un errore, la risposta torna nel formato JSON standard delle API.
Questo significa che il tuo client deve gestire in modo diverso i casi di successo e di errore:
- successo: salva il file;
- errore: leggi il JSON di risposta e gestiscilo come una normale risposta API.
Header utili nella risposta
Gli endpoint di download possono restituire alcuni header molto utili:
Content-Disposition: indica che il contenuto è un allegato e può includere il nome file;Content-Length: indica la dimensione del file in byte;Last-Modified: indica la data di ultima modifica del file;Cache-Control: contiene eventuali indicazioni di cache;X-Content-Type-Options: header di protezione del contenuto.
Quando possibile, è buona pratica leggere Content-Disposition per determinare il nome del file da salvare.
Content-Type da aspettarsi
Il tipo di file restituito dipende dall'endpoint:
- per i PDF, il content type è
application/pdf; - per i file XML, il content type può essere
text/xml; - in alcuni casi, per documenti firmati, può essere restituito
application/x-pkcs7-mime, cioè il file firmato in formato.p7m.
Download PDF
Per i documenti PDF il comportamento è diretto: l'endpoint restituisce il file PDF.
Esempi:
GET /api/v3/invoices/{invoice_id}/download/pdfGET /api/v3/creditnotes/{creditnote_id}/download/pdf
In questi casi, se la richiesta va a buon fine, puoi salvare direttamente il body della risposta come file PDF.
Download XML e file firmati
Per i documenti XML esistono endpoint dedicati, ad esempio:
GET /api/v3/invoices/{invoice_id}/downloadGET /api/v3/creditnotes/{creditnote_id}/download
Questi endpoint possono restituire:
- il file XML;
- oppure, se il documento è firmato, il file originale in formato
.p7m.
Per questi endpoint è disponibile il parametro query string prefer_xml.
Se imposti prefer_xml=true, forzi il download della versione XML anche quando il documento firmato originale è disponibile.
Esempio
Questo esempio scarica il PDF di una fattura e lo salva su disco.
curl --request GET \
--url 'https://api.shellrent.com/api/v3/invoices/00001111/download/pdf' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
--output fattura-00001111.pdf
In questo caso:
- se la richiesta ha esito positivo, il file viene salvato come
fattura-123456.pdf; - se la richiesta fallisce, la risposta non sarà un PDF ma un JSON di errore.
Esempio in PHP
Questo esempio mostra come scaricare un file PDF con Guzzle e salvarlo localmente.
<?php
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
$client = new Client([
'base_uri' => 'https://api.shellrent.com',
'http_errors' => false,
]);
$response = $client->request('GET', '/api/v3/invoices/123456/download/pdf', [
'headers' => [
'Authorization' => 'Bearer YOUR_ACCESS_TOKEN',
'Accept' => 'application/pdf',
],
]);
$statusCode = $response->getStatusCode();
$contentType = $response->getHeaderLine('Content-Type');
if ($statusCode === 200 && str_contains($contentType, 'application/pdf')) {
file_put_contents(__DIR__ . '/fattura-123456.pdf', $response->getBody()->getContents());
echo "File salvato correttamente.\n";
exit;
}
$body = (string) $response->getBody();
$data = json_decode($body, true);
echo "Errore API:\n";
print_r($data);
Esempio con prefer_xml
Questo esempio richiede il download XML di una fattura, forzando la versione XML anche se il documento è disponibile in formato firmato.
curl --request GET \
--url 'https://api.shellrent.com/api/v3/invoices/00001111/download?prefer_xml=true' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
--output fattura-123456.xml
Se non imposti prefer_xml=true, il server potrebbe restituire il file firmato originale invece del file XML.
Come gestire correttamente la risposta
Quando lavori con endpoint di download, ti conviene seguire sempre questo flusso:
- invia la richiesta autenticata;
- controlla lo status code;
- verifica il
Content-Type; - se la risposta è un file, salva il body;
- se la risposta non è un file, interpreta il body come JSON di errore.
Questo approccio evita errori comuni, ad esempio tentare di decodificare come JSON una risposta che in realtà contiene un PDF.
Buone pratiche
Se disponibile, usa Content-Disposition per recuperare il nome file proposto dal server invece di costruirlo manualmente.
Quando scarichi XML da endpoint che possono restituire anche file firmati, controlla sempre il Content-Type ricevuto prima di decidere l'estensione del file.
Una risposta 200 OK su un endpoint di download non contiene il wrapper JSON standard: contiene direttamente il file.
Gli errori continuano invece a usare il formato JSON standard delle API, quindi il tuo codice deve saper distinguere chiaramente i due casi.