2010-02-10 12 views

Antwort

10

Der einzige wirkliche Unterschied scheint zu sein, dass es für Clients einfacher ist, wenn sie absolute URIs konsumieren, anstatt sie aus der relativen Version zu konstruieren. Natürlich würde dieser Unterschied ausreichen, um mich dazu zu bringen, die absolute Version zu machen.

12

Es hängt davon ab, wer den Clientcode schreibt. Wenn Sie den Client und den Server schreiben, macht das keinen großen Unterschied. Sie werden entweder die Mühe haben, die URLs auf dem Client oder auf dem Server zu erstellen.

Wenn Sie jedoch den Server erstellen und erwarten, dass andere Benutzer Clientcode schreiben, werden sie Sie sehr viel mehr lieben, wenn Sie vollständige URIs bereitstellen. Resolving relative URIs kann ein bisschen schwierig sein. Wie sie zuerst gelöst werden, hängt vom zurückgegebenen Medientyp ab. Html hat das Basis-Tag, Xml kann xml: base-Tags in jedem verschachtelten Element haben, Atom-Feeds können eine Basis im Feed und eine andere Basis im Inhalt haben. Wenn Sie Ihrem Client keine expliziten Informationen über den Basis-URI bereitstellen, müssen sie den Basis-URI aus dem Anforderungs-URI oder möglicherweise aus dem Kopf des Inhaltsbereichs abrufen. Und pass auf diesen nachgestellten Schrägstrich auf. Der Basis-URI wird ermittelt, indem alle Zeichen rechts vom letzten Schrägstrich ignoriert werden. Dies bedeutet, dass ein abschließender Schrägstrich jetzt sehr wichtig ist, wenn relative URIs aufgelöst werden.

Das einzige andere Problem, das eine kleine Erwähnung erfordert, ist die Dokumentgröße. Wenn Sie eine große Liste mit Elementen zurückgeben, bei denen jedes Element mehrere Links enthalten kann, kann die Verwendung absoluter URLs Ihrer Entität eine erhebliche Menge an Bytes hinzufügen, wenn Sie die Entität nicht komprimieren. Dies ist ein Perf-Problem, und Sie müssen entscheiden, ob es von Fall zu Fall wichtig ist.

7

Wenn Ihre Anwendung skaliert, möchten Sie möglicherweise Lastverteilung, Failover usw. durchführen. Wenn Sie absolute URIs zurückgeben, folgen Ihre clientseitigen Apps Ihrer sich entwickelnden Serverkonfiguration.

+0

Vorausgesetzt, Sie definieren "absolut" als absoluten Pfad (zB '/ xxx/yyy ...') und nicht als vollständig qualifizierten URI (zB 'http://api.example.com/xxx/yyy .. .'). –

2

Ein Nachteil der Verwendung von absoluten URIs ist, dass die API nicht proxisiert werden kann.

Nimm es zurück ... nicht wahr. Sie sollten nach einer vollständigen URL einschließlich der Domain suchen.

+3

Warum kann der absolute URI nicht den Hostnamen des Proxys verwenden? –

+1

Durch dieses genaue Problem im Moment arbeiten.Wir möchten, dass alle Anfragen zuerst eine Art "Lastenausgleich" -Schicht durchlaufen. Absolute URIs zu den Servern direkt brechen dieses Modell. – mag382

+0

Ich verwende Nginx, um eine Site mit absoluten URLs zu proxygrafieren. Es ist durchaus in der Lage, die Backend-URL durch die entsprechende Proxy-URL zu ersetzen. Genauer gesagt https://windyroad.artifactoryonline.com (mit vollständig qualifizierten URLs und voll qualifizierten Weiterleitungen) zu https://repo.windyroad.com.au –

57

Es gibt eine subtile konzeptionelle Ambiguität, wenn Leute "relative uri" sagen.

von RFC3986's definition, eine generische uri enthält:

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 

Die heikle Sache ist, wenn Schema und Autorität weggelassen werden, der „Weg“ Teil selbst entweder ein absoluter Pfad sein kann (beginnt mit „/“) oder ein "wurzelloser" relativer Pfad. Beispiele:

  1. Ein absoluter uri oder eine vollständige uri: "http://example.com:8042/over/there?name=ferret"
  2. Und das ist ein relativ uri, mit absolutem Pfad: "/ über/es"
  3. Und das ist ein relativ uri, mit relativem Pfad: "hier" oder "./hier" oder "../hier" oder etc.

Also, wenn die Frage war, „ob ein Server relativen Pfad in ruhiger Reaktion erzeugen sollte“, lautet die Antwort „Nein“ und die detail reason is available here. Ich denke, die meisten Leute (include mich) gegen "relative Uri" sind eigentlich gegen "relativen Pfad". In der Praxis kann das meiste serverseitige MVC-Framework leicht relative uri mit absolutem Pfad wie "/ absolute/path/to/the/controller" generieren, und die Frage wird "ob die Server-Implementierung vorangestellt werden soll ein Schema: // Hostname: Port vor dem absoluten Pfad ". Wie die Frage des OP. Ich bin mir nicht ganz sicher.

Auf der einen Seite, ich denke immer noch, dass Server eine vollständige URI zurücksenden wird empfohlen. Allerdings sollte der Server never hardcode the hostname:port thing inside source code like this sein (sonst würde ich lieber auf relative uri mit absolutem Pfad zurückgreifen). Die Lösung besteht darin, dass die Server-Seite dieses Präfix immer aus dem Header "Host" der HTTP-Anfrage bezieht. Nicht sicher, ob das für jede Situation funktioniert.

Auf der anderen Seite scheint es nicht sehr lästig für den Client, die "http://example.com:8042" und den absoluten Pfad zu verketten. Immerhin kennt der Client dieses Schema und den Domain-Namen, wenn er die Anfrage an den Server sendet, richtig?

Alles in allem würde ich sagen, empfehlen absolute URI, möglicherweise Fallback zu relativen URI mit absoluten Pfad verwenden, nie relativen Pfad verwenden.

+2

Dies ist eine gute Antwort (+1), der ich zustimme die endgültige Schlussfolgerung. In meiner Antwort argumentiere ich jedoch, dass die HTTP-Spezifikation * * durch * * definiert, "absolut", um auf einen absoluten * Pfad * zu verweisen, nicht eine vollständig qualifizierte URI. Also stimme ich nicht mit Ihrem (2) überein - es ist * eine absolute URI, aber eine, für die der Client das Netzwerkprotokoll und den Host ableiten muss, also ist es kein voll qualifizierter URI. Und deshalb stimme ich auch nicht mit Ihrer Definition von (1) überein, die * sowohl * eine vollständige URI als auch eine absolute URI ist. –

+0

Danke für den Kommentar. Ich lehne nur das absolute Pfad- und relative Pfadkonzept vom Dateisystem aus. Anders ausgedrückt, sehe ich keinen wesentlichen Unterschied zwischen deiner und meiner Meinung. Sie empfehlen auch Formular 1 & 2, und Sie gegen Formular 3, nicht wahr? – RayLuo

+2

Praktisch bin ich für (2); Ich denke (1) erfordert, dass das Backend zu viel HTTP-spezifisches Wissen hat (das bedeutet über die Details der spezifischen HTTP-Umgebung, nicht HTTP im Allgemeinen), und (3) scheint zu viel von dem Client zu benötigen. * Aber *, meine Argumentation basierte auf dem ursprünglichen Entwurf der Spezifikation, und die Beispiele wurden in einer späteren Version in einer Weise geändert, die meine Argumentation ungültig macht. –

3

Sie sollten immer die vollständige URL verwenden. Es fungiert als eindeutiger Bezeichner für die Ressource, da alle URLs eindeutig sein müssen.

Ich würde auch argumentieren, dass Sie konsequent sein sollten. Da der Location HTTP-Header eine vollständige URL basierend auf der HTTP-Spezifikation erwartet, wird die vollständige URL beim Erstellen einer neuen Ressource im Location-Header an den Client gesendet. Es wäre seltsam, wenn Sie eine vollständige URL in der Location-Kopfzeile und dann relative URIs in den Links in Ihrem Antworttext angeben würden.

+0

Nun, die HTTP-Spezifikation für den Location-Header sagt absoluten URI. Ein absoluter URI muss ein Schema (z. B. http) enthalten. –

+0

Aber die Frage ist nicht, wie kontextlose opaque * Bezeichner * zu konstruieren, es fragt, wie man * Links *. Letzteres kann "am selben Netzwerkstandort wie dieses Dokument" richtig ableiten, und genau das ist das Beispiel eines "Location" -Headers in der Spezifikation - ein absoluter URI, der das URI-Schema oder den Netzwerkstandort des Servers nicht enthält. Während Links und IDs oft zusammengeführt werden, sind sie nicht das Gleiche - erstere hat Kontext, letzteres nicht. –

+0

Können Sie einen Link zu dem Teil der Spezifikation senden, von dem Sie sprechen? –

1

Eine wichtige Überlegung bei großen API-Ergebnissen ist der zusätzliche Netzwerk-Overhead, der die vollständige URI wiederholt einschließt. Ob Sie es glauben oder nicht, gzip löst dieses Problem nicht vollständig (nicht sicher warum). Wir waren schockiert darüber, wie viel Platz die vollständige URI einnahm, als Hunderte von Links in einem Ergebnis enthalten waren.

3

Mit RayLou's trichotomy hat sich meine Organisation für favorisiert (2). Der Hauptgrund ist die Vermeidung von XSS-Angriffen (Cross-Site Scripting). Das Problem besteht darin, dass Angreifer, die einen eigenen URL-Stamm in die vom Server zurückkehrende Antwort eingeben können, nachfolgende Benutzeranforderungen (z. B. eine Authentifizierungsanforderung mit Benutzername und Kennwort) an den eigenen Server des Angreifers weiterleiten können.

Einige haben das Problem aufgeworfen, Anfragen an andere Server für Lastverteilung umleiten zu können, aber ich würde wetten, dass es bessere Möglichkeiten gibt, den Lastenausgleich zu aktivieren, ohne dies explizit zu tun Umleitung von Clients zu verschiedenen Hosts.

* bitte lassen Sie mich wissen, wenn es irgendwelche Fehler in dieser Linie der Argumentation gibt. Das Ziel ist natürlich nicht, alle Angriffe zu verhindern, sondern zumindest eine Angriffsfläche.

+0

Schön, dass meine vorherige Antwort für Ihre Organisation hilfreich war. Ja, ich persönlich bevorzuge auch (2), a.k.a. schemaloser absoluter Pfad. Aber ich bin neugierig auf Ihre Argumentation. Wie haben Sie Ihren Kunden dazu gezwungen, nur Ihre schemloselose URL zu akzeptieren? Ein generischer Client, z. B. ein Browser, würde eine URL ohne Schema nicht ablehnen. Also nehme ich an, dass Sie Ihren eigenen clientseitigen Code schreiben müssen, um URLs zu validieren, bevor Sie ihnen tatsächlich folgen? Obwohl dies technisch machbar (aber nicht notwendigerweise nützlich) ist, ist diese Art der clientseitigen Validierung typischerweise nicht Teil der REST- oder HATEOAS-Diskussion. – RayLuo

Verwandte Themen