Skip to content
This repository was archived by the owner on Jul 7, 2022. It is now read-only.

Spiking

mscholz11 edited this page Jul 1, 2015 · 56 revisions

Hier finden sich Antworten und weiterführende Fragen zum Spiking.

Übergeordnete Ziele des Spikings

  • Technische Risiken + Erweiterbarkeit klären
  • Technisches Konzept erstellen + Technologiewahl begründen
  • Entwicklungsaufwand abschätzen

TODOs

  • MVP (Widget und Wordpress Plugin) abschätzen
  • Manchmal werden die globalen Objekte (Backbone etc.) nicht rechtzeitig geladen
  • JavaScript-Framework auswählen und die Wahl begründen
  • DOM vs. IFRAME entscheiden und begründen
  • Gestylte Version von einem API Call spiken (z.B. Anzeige eines einzelnen Produkts)
  • Staging-Umgebung auf Heroku einrichten
    • corsproxy
    • site.js
    • Demo Kunden-Webseite, die das Ganze einbindet

CORS vs. JSONP

Aus Sicherheitsgründen ist es JavaScript nicht erlaubt, HTTP-Requests auf eine fremde Domain auszuführen. Hierfür benötigen wir CORS und/oder JSONP. CORS ist ein Standard über den ein Browser einen Server fragen kann, ob dieser Cross-Site-Zugriffe erlaubt. JSONP generiert ein Script-Tag auf der Website, in die das Widget eingebunden ist, und erlaubt so GET-Requests auf beliebige Domains.

Verfügbarkeit

CORS wird erst ab IE ≥ 10, FF ≥ 3.5, Chrome ≥ 3, Safari ≥ 4 und Opera ≥ 12 supported (Übersicht). IE 8 & 9 supporten CORS nur limitiert über das XDomainRequest Objekt. Ein Fallback wäre aber möglich.

In Einzelfällen könnte es zu Problemen mit Firewalls und Proxys kommen, die möglicherweise HTTP-OPTIONS-Requests blockieren. CORS verwendet diese, um anzufragen, ob ein Server Cross-Origin-Anfragen erlaubt.

JSONP ist ein Hack, der in allen Browsern funktionieren sollte. JSONP ist bei Cross-Site-Angriffen gefährlicher, da über die Callback-Funktion beliebiger Code im Browser ausgeführt werden kann.

POST-Requests

JSONP erlaubt uns nur GET-Requests über die API. Es könnte also schwierig werden, z.B. den Warenkorb über die API zu befüllen. Falls der Aufwand, JSONP in eurer API zu unterstützen, zu groß sein sollte, könnten wir eventuell über einen Proxy das JSON der API in JSONP verwandeln.

Asynchronität

Es ist wohl nicht zu vermeiden, dass JSONP-Requests nicht komplett asynchron ausgeführt werden, wodurch die Ladezeit der Websites, in die das Widget eingebunden ist, negativ beeinflusst wird.

Empfehlung

CORS ist alt genug, um in allen Browsern, die nicht älter sind als 6 Jahre, unterstützt zu werden. Ein Fallback auf JSONP wäre möglich und könnte auch nachträglich noch implementiert werden, wenn die API JSONP-Anfragen unterstützt.

JavaScript-Framework

Das Widget erfordert nicht viele Framework-Funktionen, da es hauptsächlich einfache API-Anfragen rendert. Später kommen evtl. noch weitere Anforderungen dazu (Suche, Sortieren, ...), die jedoch auch noch ohne Framework realisierbar wären.

Außerdem wird es auf den verschiedensten Webseiten über alle möglichen Internetverbindungen von Edge bis DSL geladen, weshalb wir Wert auf eine geringe Größe unseres JavaScript-Codes Wert legen.

  • Ember: Viel zu mächtig und groß (500 kb).
  • Angular: dito.
  • Gar-Kein-Framework: Wäre am schnellsten/kleinsten, aber evtl. schwieriger zu warten.
  • Backbone/jQuery/underscore: Klein genug um in beliebigen Seiten eingebunden zu und sehr bekannt um auch von Anderen später gewartet zu werden.
  • micro frameworks (z.B. ajax, lodash): Noch kleiner, für Version 1.0 vollkommen ausreichend, vielleicht sogar für immer.

Empfehlung

Wir beginnen mal mit den nötigsten micro frameworks, falls wir davon doch zu viele brauchen, nehmen wir jQuery oder Backbone, um die Wartung später zu erleichtern.

Script vs. iframe

Das Widget kann entweder per Script-Tag oder als iframe eingebunden werden. Diese Entscheidung ist grundlegend, da wir über den Code zur Einbindung des Widgets langfristig wenig Kontrolle haben werden, wenn dieser nicht via CMS-Plugin, sondern quasi “manuell” in Websites eingebunden wird.

Flexibilität

Auf die Größe und Position eines iframes haben wir als Third-party keinen Einfluss. Das Widget wäre für immer limitiert auf den iframe selbst und die vom Einbindenden gewählte Größe des iframe. Damit sind auch keine Overlays über der Seite möglich.

Die Script-Lösung ermöglicht uns Größe und Position des Widgets entweder komplett selbst zu bestimmen oder dem Einbindenden die Möglichkeit zu geben, Größe und Position zu beeinflussen.

Isolation

Der Inhalt eines iframes ist komplett isoliert vom Rest der Website in die das Widget eingebunden wird. Das Widget kann bei der Einbindung nur über Parameter in der URL beinflusst werden.

Bei der Einbindung via Script hingegen, müssen JavaScript und CSS durchgehend genamespaced werden. Für uns sicher kein Problem, aber etwas, worauf wir achten müssen. Außerdem kann eine kleine JavaScript-API zur Verfügung gestellt werden, über die z.B. die Shop-ID gesetzt oder das Widget anderweitig konfiguriert werden kann.

Styling

Das Styling des Widgets im iframe kann nicht durch den Einbindenden angepasst werden. Das heißt auch, dass wir die volle Kontrolle über das Aussehen des Widgets haben, aber selbst kleine Anpassungen von Position, Schriftart oder Farbe durch den Einbindenden nicht möglich sind.

Bei der Script-Lösung kann das Styling des Widgets kann entweder von uns vorgegeben und vom Einbindenden angepasst werden oder komplett und unveränderbar von uns bestimmt werden (Inline-Styles).

Traffic

Eine via iframe eingebundene Seite wird immer geladen, sobald die Seite in die der iframe eingebunden ist, geladen wird. Wir müssten also bei jedem Request eine komplett gerenderte Seite mit Bildern ausliefern.

Bei der Einbindung via Script hätten wir die Möglichkeit, den eigentlichen Content erst zu laden, wenn der Script-Container im Viewport des Browsers ist. Also dann, wenn der Besucher das Widget wirklich sieht. Hierdurch könnten wir einerseits Traffic sparen und andererseits feststellen, wie oft und wo das Widget überhaupt gesehen wird. Ich glaube Disqus macht das ähnlich.

Empfehlung

Wir fangen mit DOM an. Sollten wir auf Darstellungsfehler auf Grund von CSS Konflikten stoßen, können wir immer noch dynamisch einen IFRAME einfügen.

Das Snippet, dass auf der Endkunden-Webseite eingebunden wird, sollte sich möglichst nie wieder ändern, da bietet sich auch eine DOM-Lösung an.

Weiterführende Fragen

Die folgenden Fragen sind nicht unbedingt wichtig für das Spiking, sie sollten aber geklärt werden, bevor das eigentliche Projekt beginnt.

  • Soll das Widget (wie Disqus) immer gleich aussehen oder sollen Shop-Betreiber die Möglichkeit haben, über das Shop-Backend z.B. die Hauptfarben des Shops festzulegen, welche das Widget des Shops dann verwendet?

    • Shop Betreiber kann Anpassungen machen, das Widget soll sich ins Design einpassen (Schriften, etc.)
  • Was sehen Besucher einer Website zuerst, wenn das Widget geladen wird? Ein einzelnes Produkt, alle oder die ersten Produkte eines Shops? Wie groß stellt ihr euch das Widget im Normalzustand vor?

    • Erstmal alle Produkte, dann Einzelne.
  • Ist es euch möglich, CORS-Header in eure API zu integrieren oder zusätzlich zur JSON-API auch JSONP zu unterstützen? Alternativ wäre ein einfacher CORS-Proxy denkbar.

    • TODO ePages: CORS Header? --> Answer: cors headers haben wir schon bei unserer rest api
  • Browserkompatibilität? Was brauchen wir da? Das beeinflusst CORS, Framework, localStorage, uvm.

    • TODO ePages: Browser Versionen? ** Chrome: Aktuelle Version und letzte Version ** Firefox: Aktuelle Version und letzte Version ** Safari: Aktuelle Version und letzte Version ** IE: IE 10 und höher
  • Wann wollen wir den Warenkorb bei ePages anlegen? Wenn das erste Produkt reingelegt wird oder erst beim Bezahlen?

    • Sofort anlegen.
  • Müssen wir Variations berücksichtigen? Die sind uns noch etwas unklar.

    • Variations sollten im Produkte-API-Call enthalten sein, oder im Produkt-Detail-Call.
    • TODO ePages: Nochmal klären. --> Antwort: Jede Variation ist ein eigenes Produkt. Im Call GET /shops/{shopId}/products bzw. GET /shops/{shopId}/products/{productId} ist ein Link zum zugehörigen variations-Call angegeben In diesem variations-Call (GET /shops/{shopId}/products/{productId}/variations) sind die Variationsattribute angegeben, durch die sich die Variationen unterscheiden (und die also auf der Produktdetailseite als Dropdowns angezeigt werden) und für jede verfügbare Variation ein Link zum Product-Call (also sowas: "href":".../products/var1GUID“)
    • TODO ePages: Das ist in der Doku noch unklar.

Clone this wiki locally