Risoluzione dell'immagine in un'interfaccia RESTful

3

Sfondo

Ho un'API HTTP RESTful.

Ho una risorsa.

GET /my/cat HTTP/1.1

I client potrebbero voler recuperare la rappresentazione dell'immagine di questa risorsa.

GET /my/cat HTTP/1.1
Accepts: image/png

problema

I client hanno una vasta gamma di risoluzioni necessarie ed è importante che ricevano la risoluzione corretta. Se è troppo grande, consumerà una larghezza di banda eccessiva. Se è troppo piccolo, non avrà un bell'aspetto. (Per non parlare del downsampling / antialiasing che il client dovrà fare per cercare di adattarlo a ciò che voleva, con risultati discutibili.)

Opzioni

Parametro query

GET /my/cat?resolution=100 HTTP/1.1
Accepts: image/png

Funziona, ma è un po 'strano. Se cambi ad accettare text/xml nella stessa posizione (URL), non ha più senso. E richiede il mangling dell'URL, che non è veramente RESTful.

Parametro di tipo MIME

GET /my/cat HTTP/1.1
Accepts: image/png; resolution=100 

Questo ha un senso, poiché si riferisce molto direttamente al particolare formato che sto richiedendo, in modo simile all'aggiunta di un parametro charset per le risposte testuali. Non l'ho mai visto prima, però.

Intestazione personalizzata

GET /my/foo HTTP/1.1
Accepts: image/png
X-Image-Resolution: 100

Non riesco a vedere molto male in questo. Le intestazioni personalizzate sono completamente arbitrarie e possono fondamentalmente riguardare qualsiasi cosa riguardante una richiesta e può essere tentato di usarle eccessivamente.

Qual è il modo più standard per farlo? O almeno il modo più "normale" o "previsto"?

    
posta Paul Draper 05.11.2015 - 22:43
fonte

3 risposte

5

What is most standard way to do this? Or at least the most "normal" or "expected" way?

Non ho statistiche, ma posso dirti cosa mi aspetto e cosa ho visto in interfacce più o meno RESTful.

Prima di tutto, non mi aspetto che un'immagine cat sia solo un'altra rappresentazione della risorsa / my / cat. Mi aspetterei che sia una sottorisorsa (una sorta di componente) della risorsa gatto. Negli ambienti HTTP, le immagini di solito assomigliano ai file, con un'estensione che indica i loro formati. Quindi mi aspetterei /my/cat/image.jpg e il mio / cat / image.png.

Per quanto riguarda la risoluzione, è comune offrire un'immagine in due o tre risoluzioni, indirizzata al desktop rispetto alle piattaforme mobili (due) o ai dispositivi desktop, tablet e smartphone (tre). Questo è espresso nei nomi dei file, ad es. /my/cat/image-large.jpg e /my/cat/image-small.jpg.

Bene, questo suona davvero tradizionale, eh? Nessun uso elaborato di intestazioni HTTP ecc. Sì, è così che viene utilizzato HTTP, è quello che penso che la maggior parte della gente si aspetta.

A proposito, se hai un'interfaccia RESTful, mi aspetterei che / my / cat restituisca una risposta JSON o XML (magari a seconda dell'intestazione Accept, in effetti), che include collegamenti alle immagini:

   {
      "name" : "Tom",
      "image" : {
         "large" : { "href" : "/my/cat/image-large.jpg" },
         "small" : { "href" : "/my/cat/image-small.jpg" }
      }
   }

Vedi JAREST per ulteriori dettagli su ciò che raccomando per le API RESTful.

    
risposta data 06.11.2015 - 14:41
fonte
1

Ok, hai una risorsa in /my/cat .

Supponiamo che un gatto abbia un nome e un colore.

Quando richiedi:

GET /my/cat HTTP/1.1
Accepts: application/json

Hai:

{
  name: "Fluffy",
  color: "black"
}

Quando richiedi:

GET /my/cat HTTP/1.1
Accepts: image/png

Si ottiene un'immagine simpatica e animata di un gatto nero, magari con un'etichetta "Fluffy" da qualche parte. Questa è una rappresentazione dell'immagine di cat.

Quando richiedi:

GET /my/cat/photo HTTP/1.1
Accepts: image/png

Ottieni la foto reale di questo particolare gatto come immagine PNG. Si noti che questa è una richiesta per un percorso diverso, una richiesta per una sotto-risorsa - la foto del gatto non è un'altra rappresentazione di una risorsa cat (che ha nome + colore).

Quando richiedi:

GET /my/cat/photo HTTP/1.1
Accepts: image/jpeg

Ottieni foto JPEG di questo gatto.

Ora, le specifiche HTTP dicono che un percorso diverso significa una risorsa diversa e che include estensioni di file (non hanno alcun significato speciale in HTTP). Aggiungendo .jpg a un percorso di risorsa stai creando un percorso diverso, che punta a una risorsa diversa.

Per spiegare meglio perché questo è importante guarda la seguente richiesta:

GET /my/cat/photo.jpg HTTP/1.1
Accepts: image/png

Si noti che abbiamo specificato .jpg nel percorso, ma accettiamo solo image/png . Questo non ha molto senso. Cosa dovrebbe fare il server in questo caso? I server ben funzionanti non trattano le estensioni dei file nei percorsi di richiesta in alcun modo speciale e restituiscono un file PNG per tale richiesta. Quindi otteniamo l'immagine PNG di /my/cat/photo.jpg risorsa, non /my/cat/photo risorsa.

Che ne dici di specificare la risoluzione / densità di pixel / qualità dell'immagine richiesta?

Se i creatori di browser avevano le loro priorità, questo è ciò che accadrebbe sul dispositivo DPI (retina):

GET /my/cat/photo HTTP/1.1
Accepts: image/jpeg; ppi=255;

E su smartphone di fascia bassa:

GET /my/cat/photo HTTP/1.1
Accepts: image/jpeg; ppi=100;

Utilizzeresti <img src="/my/cat/photo"> nella tua pagina e il browser aggiungerebbe questi bit extra quando richiedi la risorsa. Il server potrebbe quindi restituire l'immagine appropriata in base al valore ppi . Questo è solo un esempio teorico, vorrei che i browser lo facciano.

Dato che non abbiamo la funzionalità sopra descritta nei nostri browser web, dobbiamo essere espliciti sulla qualità dell'immagine quando effettui una richiesta.

Quindi, che dire di avere /cat/photo-small.jpg , /cat/photo-big.jpg etc?

Se vuoi eseguire correttamente REST / HTTP, dovresti utilizzare lo stesso URL per tutte le "varianti" della tua immagine. I due percorsi precedenti sono due risorse diverse nella semantica REST / HTTP.

Ok, per quanto riguarda il parametro di query, /cat/photo?size=small e /cat/photo?size=big ?

In base alle specifiche HTTP, l'intero URL identifica una risorsa e include protocollo, dominio, percorso e stringa di query. Quindi i due percorsi precedenti sono anche due risorse diverse nella semantica REST / HTTP. Sfortunatamente, le stringhe di query non sono realmente compatibili con la corretta negoziazione dei media (tipo, lingua, qualsiasi altra variante) negoziazione .

E non è possibile impostare alcuna intestazione HTTP (come X-Image-Resolution ) quando si dichiarano i tag <img> nel codice HTML o quando si digita l'URL dell'immagine nella barra degli indirizzi del browser.

Non penso che ci sia davvero un modo "normale" o "standard" per raggiungere il tuo obiettivo al momento. Vedo spesso persone che utilizzano percorsi di immagine diversi o interrogano le stringhe per specificare le varianti dell'immagine, il che funziona in pratica.

E va bene, ma poi dovremmo tutti smettere di fingere di fare il corretto HTTP;)

    
risposta data 02.05.2017 - 21:06
fonte
0

Nonostante questa sia una vecchia domanda, mi piacerebbe contribuire.

Prima di tutto, come al solito, KISS.

  1. Il componente

    Query di un URI contiene un set di parametri da interpretare come variazione o derivato della risorsa identificata dal percorso componente.

    Dal mio punto di vista i prossimi URI sono simili:

    GET /resources?page=0&size=10

    GET /resource/0/image?width=x&high=y

    GET /resource/0/image?ratio=0.5

    Tutti e tre stanno dimensionando la rappresentazione della risorsa.

  2. Accetta Intestazione HTTP. Rilascio del supporto per testo / * o applicazione / * tipi di contenuto

    GET /my/cat HTTP/1.1

    Accept: text/*

    ...

    HTTP/1.1 406 Not Acceptable

  3. Prova a evitare le estensioni dei file nell'URI per indicare i formati di rappresentazione. Affidati a tipi di media e intestazioni HTTP. A meno che non desideri ottenere il file direttamente dalla posizione remota anziché tramite l'API.

Collegamenti che potrebbero interessare:

risposta data 03.05.2017 - 00:17
fonte

Leggi altre domande sui tag