2010-02-10 22 views

risposta

10

L'unica vera differenza sembra essere che è più semplice per i client se stanno consumando URI assoluti invece di doverli costruire dalla relativa versione. Certamente, questa differenza sarebbe sufficiente per influenzarmi a fare la versione assoluta.

12

Dipende da chi sta scrivendo il codice cliente. Se stai scrivendo client e server, non fa molta differenza. Soffrirai il dolore di costruire gli URL sul client o sul server.

Tuttavia, se si sta costruendo il server e ci si aspetta che altre persone scrivano il codice client, allora ti adoreranno molto di più se fornirai URI completi. Risolvere gli URI relativi può essere un po 'complicato. In primo luogo, come li risolvi dipende dal tipo di supporto restituito. Html ha il tag base, Xml può avere xml: i tag base in ogni elemento nidificato, i feed Atom potrebbero avere una base nel feed e una base diversa nel contenuto. Se non fornisci al tuo cliente informazioni esplicite sull'URI di base, allora devono ottenere l'URI di base dall'URI della richiesta, o forse dall'intestazione Content-Location! E attenzione per quel taglio finale. L'URI di base viene determinato ignorando tutti i caratteri a destra dell'ultima barra. Ciò significa che la barra finale è ora molto significativa quando si risolvono gli URI relativi.

L'unico altro problema che richiede una piccola menzione è la dimensione del documento. Se si restituisce un ampio elenco di elementi in cui ogni elemento può avere più collegamenti, l'utilizzo di URL assoluti può aggiungere una quantità significativa di byte all'entità se non si comprime l'entità. Questo è un problema prof e devi decidere se è significativo caso per caso.

7

Man mano che l'applicazione viene ridimensionata, è possibile eseguire il bilanciamento del carico, il failover ecc. Se si restituiscono URI assoluti, le app sul lato client seguiranno la configurazione in evoluzione dei server.

+0

Se si definisce "assoluto" come percorso assoluto (ad esempio '/ xxx/yyy ...') e non come un URI pienamente qualificato (ad esempio 'http://api.example.com/xxx/yyy .. .'). –

2

Uno svantaggio dell'utilizzo di URI assoluti è che l'API non può essere proxy.

Riprenderlo ... non è vero. Dovresti andare per un URL completo incluso il dominio.

+3

Perché l'URI assoluto non può utilizzare il nome host del proxy? –

+1

Esaminare questo problema esatto al momento.Vogliamo che tutte le richieste attraversino prima una sorta di strato di "bilanciamento del carico". Gli URI assoluti ai server interromperanno direttamente questo modello. – mag382

+0

Sto utilizzando Nginx per eseguire il proxy di un sito con URL assoluti. È perfettamente in grado di sostituire l'URL di back-end con l'URL proxy equivalente. In particolare è proxing https://windyroad.artifactoryonline.com (che ha URL completi e reindirizzamenti completi) a https://repo.windyroad.com.au –

57

C'è una sottile ambiguità concettuale quando la gente dice "uri relativo".

Con RFC3986's definition, un uri nucleo contiene:

URI   = scheme ":" hier-part [ "?" query ] [ "#" fragment ] 

    hier-part = "//" authority path-abempty 
      /path-absolute 
      /path-rootless 
      /path-empty 

    foo://example.com:8042/over/there?name=ferret#nose 
    \_/ \______________/\_________/ \_________/ \__/ 
     |   |   |   |  | 
    scheme  authority  path  query fragment 

La cosa difficile è, quando regime e l'autorità sono omessi, la parte "percorso" stesso può essere un percorso assoluto (comincia con "/") o un percorso relativo "senza radici". Esempi:

  1. Un URI assoluto o un URI completo: "http://example.com:8042/over/there?name=ferret"
  2. E questo è un URI relativo , con percorso assoluto: "/ sopra/là"
  3. E questo è un relativa uri, con relativo percorso: "qui" o "./here" o "../here" o ecc.

Quindi, se la domanda era "se un server dovrebbe produrre percorso relativo in risposta riposante", la risposta è "No" e il detail reason is available here. Penso che la maggior parte delle persone (includi me) contro "relativa uri" siano in realtà contro "percorso relativo".

E in pratica, la maggior parte sul lato server framework MVC può facilmente generare uri relativo con il percorso assoluto come "/ assoluto/path/to/la/regolatore", e la questione diventa "se l'attuazione server deve anteporre uno schema: // nomehost: porta davanti al percorso assoluto ". Come la domanda dell'OP. Non sono abbastanza sicuro di questo.

Da un lato, continuo a pensare che il server restituisca un uri completo. Tuttavia, il server dovrebbe never hardcode the hostname:port thing inside source code like this (altrimenti preferirei eseguire il fallback a relativo uri con percorso assoluto). La soluzione è lato server sempre ottenendo tale prefisso dall'intestazione "Host" della richiesta HTTP. Non sono sicuro se questo funziona comunque per ogni situazione.

D'altra parte, non sembra molto problematico per il client concatenare il "http://example.com:8042" e il percorso assoluto. Dopo tutto, il client conosce già lo schema e il nome del dominio quando invia la richiesta al server giusto?

Tutto sommato, direi, consiglia di utilizzare uri assoluto, possibilmente fallback a relativo uri con percorso assoluto, mai usare il percorso relativo.

+2

Questa è una buona risposta (+1) che concordo con la conclusione finale. Tuttavia nella mia risposta sostengo che la specifica HTTP definisce, * per esempio *, "assoluto" per riferirsi a un * percorso * assoluto, non a un URI pienamente qualificato. Quindi non sono d'accordo con il tuo (2) - è * è * un URI assoluto, ma uno per il quale il client deve inferire il protocollo di rete e l'host, quindi non è un URI pienamente qualificato. E, quindi, anch'io non sono d'accordo con la tua definizione di (1) che è * sia * un URI completo che un URI assoluto. –

+0

Grazie per il commento. Prendo solo in prestito il percorso assoluto e il concetto di percorso relativo dal file system. Termini diversi a parte, non vedo differenze sostanziali tra la tua opinione e la mia. Raccomanda anche il modulo 1 e 2 e tu contro il modulo 3, vero? – RayLuo

+2

In pratica, sono per (2); Penso che (1) richieda al back-end di avere molte conoscenze specifiche su HTTP (cioè sui dettagli dello specifico ambiente HTTP, non su HTTP in generale), e (3) sembra richiedere troppo del client. * Ma *, il mio ragionamento si basava sulla specifica della bozza originale e gli esempi sono stati modificati in una versione successiva in modo da invalidare il mio ragionamento. –

3

È necessario utilizzare sempre l'URL completo. Agisce come identificatore univoco per la risorsa poiché gli URL devono essere tutti unici.

Vorrei anche sostenere che dovresti essere coerente. Poiché l'intestazione dell'ubicazione HTTP prevede un URL completo basato sulla specifica HTTP, l'URL completo viene rinviato nell'intestazione Location al client quando viene creata una nuova risorsa. Sarebbe strano per te fornire un URL completo nell'intestazione Location e quindi URI relativi nei link all'interno del tuo corpo di risposta.

+0

Bene, la specifica HTTP per l'intestazione Location dice URI assoluto. Un URI assoluto deve contenere uno schema (ad esempio http). –

+0

Ma la domanda non è come costruire identificatori * opachi * senza contesto, chiede come costruire * collegamenti *. Quest'ultimo può giustamente dedurre "nella stessa posizione di rete di questo documento", ed è esattamente ciò che dà l'esempio della specifica di un'intestazione 'Location' - un URI assoluto che non contiene lo schema URI o il percorso di rete del server. Mentre i collegamenti e gli ID sono spesso fusi non sono la stessa cosa: il primo ha un contesto, il secondo no. –

+0

Puoi inviare un link alla parte della specifica di cui stai parlando? –

1

Una considerazione importante nei risultati dell'API di grandi dimensioni è il sovraccarico di rete aggiuntivo di includere ripetutamente l'URI completo. Che ci crediate o no, gzip non risolve interamente questo problema (non so perché). Siamo rimasti scioccati di quanto spazio occupasse l'intero URI quando c'erano centinaia di collegamenti inclusi in un risultato.

3

Utilizzando la RayLou's trichotomy, la mia organizzazione ha optato per la promozione (2). Il motivo principale è evitare gli attacchi XSS (Cross-Site Scripting). Il problema è che se un utente malintenzionato può iniettare la propria radice URL nella risposta proveniente dal server, le successive richieste dell'utente (come una richiesta di autenticazione con nome utente e password) possono essere inoltrate al proprio server *.

Alcuni hanno sollevato il problema di essere in grado di reindirizzare le richieste ad altri server per il bilanciamento del carico, ma (anche se questa non è la mia area di competenza) Scommetto che ci sono modi migliori per abilitare il bilanciamento del carico senza dover esplicitamente reindirizzare i clienti a diversi host.

* per favore fatemi sapere se ci sono dei difetti in questa linea di ragionamento. L'obiettivo, ovviamente, non è prevenire tutti gli attacchi, ma almeno una via d'attacco.

+0

Contento che la mia precedente risposta sia stata utile per la tua organizzazione. Sì, personalmente preferisco anche (2), a.k.a. percorso assoluto senza schema. Comunque sono curioso del tuo ragionamento. Come hai fatto imporre al tuo cliente l'accettazione dell'URL senza schema? Un client generico, come un browser, non rifiuterebbe affatto un URL senza schema. Quindi presumo che tu debba scrivere il tuo codice lato client per convalidare gli URL prima di seguirli realmente? Sebbene ciò sia tecnicamente fattibile (ma non necessariamente utile), questo tipo di convalida lato client non è in genere parte della discussione REST o HATEOAS. – RayLuo

Problemi correlati