Home - Galinero/WBA2SS15HuhnHuberHaarmann GitHub Wiki

Dokumentation des Service

Definition der Ressourcen und betrachtete Alternativen

Die eindeutige Identifzierung einzelner Ressourcen stellt eines der wesentlichen Prinzipen einer REST-Architektur dar. Basierend darauf sind die Nutzer sowie Produkte individuell über URLs ansprechbar und der Nutzer erhält bei einem GET auf /users/ beispielsweise eine Liste aller Nutzer, da auch dies eine eigene (Listen-)ressource darstellt. Im Laufe der Entwicklung sorgte gerade das Ziel einer hierarchischen URL-Struktur mehrfach für Veränderungen.
Das Ansprechen einer einzelnen Produktressource innerhalb eines Baskets sieht als Resultat dieser Überlegungen nun wie folgt aus: „[..]/products/:id/basket/:pid“, enthält also sowohl User- als auch Produktids, die die Produktseiten sowie Basketinhalte individuell ansprechbar machen.

###Beschreibung der Anwendungslogik und der Datenhaltung mit Überlegungen dazu Der Dienstgeber ist in seiner wesentlichen Funktion das Bindeglied zwischen Dienstnutzer und Datenbank. Ein Nutzer unseres Webservice interagiert über seinen Browser mit dem Dienstnutzer und kann so beispielsweise die verschiedenen CRUD-Befehle senden. Dieser leitet diese Anfragen weiter an den Dienstgeber, welcher nun mit der Datenbank interagiert.
Die Wahl einer Datenbank fiel in unserem Fall auf mongodb aufgrund der größeren Verbreitung und reichhaltigerer Möglichkeiten als über das vorgeschlagene Redis.

Aufbau:

-Shop

    -usercollection  

    -productcollection  

Erhält der Service nun eine Anfrage vom Dienstnutzer, so ruft er anschließend die entsprechenden mongodb eigenen Befehle auf.
Als Beispiel der Ablauf bei der Registrierung eines Users:

-Konflikte ausschließen (Username schon vergeben?) --> Durchsuchen der Usercollection nach von Dienstnutzer erhaltenem Usernamen (findOne({user_name: username})
-a: Username schon vergeben --> Status-Fehlercode und entsprechende Meldung an Dienstnutzer
-b: Username noch nicht vergeben --> Einfügen in Usercollection und Status-Erfolgscode und entsprechende Meldung an Dienstnutzer

Anwendungslogik

Der Dienstgeber ist in der Lage, die Produkte nach Beliebtheit sortiert anzuordnen. Der Abruf dieser Funktionalität erfolgt über eine seperate URL.
Um dies zu ermöglichen, durchsucht er die komplette productCollection und fügt sie mit einer mongodb eigenen Funktion (find().toArray()) in ein zuvor angelegtes, leeres Array ein. Anschließend werden die gekauft-Attribute der Produkte miteinander verglichen und als Ergebnis der Höhe nach sortiert in JSON-Form wieder an den Dienstnutzer ausgegeben zusammen mit einem entsprechenden Statuscode.
Falls keine Produkte innerhalb der productsCollection vorhanden sind, wird ein Fehlercode und eine entsprechende Fehlermeldung an den Dienstnutzer weitergegeben.

##Dokumentation des Dienstnutzers ###Beschreibung der Anwendungslogik und der Datenhaltung Der Dienstnutzer steht als eine Art Mittler zwischen dem Browser und dem Dienstgeber. Aus dem Browser (oder auch REST-Client) wird beispielsweise ein GET-Befehl auf eine Ressource gesendet, die dieser dann weiterleitet an den Dienstgeber. Je nachdem ob der entsprechende Request erfolgreich war oder nicht, erhält er Dienstnutzer nun einen Statuscode sowie in unserem Webservice in der Regel eine Meldung und kann nun die entsprechenden Inhalte an den Browser schicken, beispielsweise ein gesuchtes Produkt. Auch hier spielen Statuscodes sowie Meldungen wieder eine gewichtige Rolle, die z.B. bei einem Registrierungs-POST entsprechende Anweisungen nach sich ziehen (if-Abfrage im ejs-Dokument, bei positivem Statuscode erscheint beispielsweise ein Alert mit einer Erfolgsmeldung und zugehöriger Nutzer-ID, ansonsten eine Fehlermeldung)
Über das reine Request des Browsers entgegen nehmen und weiterleiten, sowie schließlich die Response des Servers entgegen nehmen und weiterleiten hinaus hat der Dienstnutzer noch eine weitere wesentliche Funktion. Der Webservice nutzt für das Erstellen der Seiten EJS-Templates. Diese ermöglichen es beispielsweise bei einem GET auf users, eine Schleife zu durchlaufen und alle User mit den eingestellten Informationen (z.B. nur Vor- und Nachname wichtig, Rest wie Strasse allerdings uninteressant) darzustellen. Im Dienstnutzer findet hierbei das Rendern der EJS-Datei in html statt. Je nachdem welche Informationen der Dienstnutzer also vom Dienstgeber und auf einer tieferen Ebene von der Datenbank erhält, werden aus einem EJS-Template unterschiedliche Inhalte gerendert.

##Umsetzung der Präsentationslogik

Die Präsentation der Seite wird mit Hilfe von Bootstrap realisiert. Das bewusst einfach gehaltene Design lenkt nicht von den eigentlichen Produkten ab, die im Rahmen eines Webshops natürlich im Fokus stehen sollten. Ein Prinzip das sich in der Vergangenheit auch die Größen des Online-Handels wie etwa amazon oder ebay zunutze machten.

Die Navigationsleiste beinhaltet den Warenkorb, die meist gekauften Produkte, das Profil des Nutzers und eine Suche für Produkte und bietet damit eine gute Zugänglichkeit zu den Kernelementen dieses Webservices.
Unter der Navigationsleiste ist der Inhalt in einem zentralen div angelegt, in dem auf jeder einzelnen Seite die verschiedenen aus ejs gerenderten Inhalte angezeigt werden.
Wird das Fenster verkleinert, oder die Seite auf einem kleineren Display angezeigt, so ändert sich die Anordnung der Seite. Alle Inhalte können so, selbst bei einer bedeutend geringeren Auflösung, ohne Fehler angezeigt werden und die Seite ist auch für Smartphone oder Tablet Nutzer geeignet.

##Ressourcentabelle

Ressource Methode Semantik Request-Type Response-Type
/login POST Übertragen von Anmeldeinformationen application/json application/json
/users POST Neuen User hinzufügen application/json application/json
/users GET Alle registrierten Nutzer auslesen text/plain application/json
/users/:id GET Liest Nutzerinformationen aus text/plain application/json
/users/:id PUT Verändert Nutzerinformationen application/json application/json
/users/:id DELETE Nutzer löschen application/json application/json
/products POST Neues Produkt hinzufügen application/json application/json
/products PUT Verändert Produktinformationen application/json application/json
/products GET Alle registrierten Produkte auslesen text/plain application/json
/products/:id GET Produkt auslesen text/plain application/json
/products/:id DELETE Produkt löschen application/json application/json
/products/:id/basket/:id GET Produkt in Warenkorb von Nutzer hinzufügen text/plain application/json
/products/:id/basket/:id DELETE Produkt aus Warenkorb von Nutzer entfernen application/json application/json
/products/:id/basket GET Warenkorb von Nutzer auslesen text/plain application/json
/products/:id/basket/ DELETE Warenkorb von Nutzer löschen application/json application/json
/products/:id/basket/:id PUT Anzahl eines Produktes in Warenkorb verändern application/json application/json
/logic/:id GET Alle registrierten Produkte nach Beliebtheit sortiert auslesen text/plain application/json
/start GET Loginseite aufrufen text/plain text/html
/registrierung GET Ressource (Nutzer-)Registrierung aufrufen text/plain text/html
/admin/produktregistrierung GET Ressource Produktregistrierung aufrufen text/plain text/html
/admin/products GET Produktübersicht für Admin (mit entsprechenden CRUD-Optionen) text/plain text/html
/admin/produktsuche GET Ressource Produktsuche aufrufen text/plain text/html
/admin/produktsuche/suche/:query GET Produkt suchen text/plain text/html

##Szenarien Paul Wilhelmi, 32, männlich, Inhaber eines Webshops für Gartenmöbel Paul hatte schon lange den Wunsch, seinen potentiellen Kundenkreis zu erweitern. Sein kleines Geschäft für Gartenmöbel ist seit Jahrzehnten im Familienbesitz, und liegt im etwas ländlicheren Herne bei Bochum. Gerade Kunden aus entfernteren Gegenden sind aktuell unerreichbar und anstatt mehr Kunden zu bekommen, ziehen immer mehr potentielle in die Großstädte.

Gertrude Müller, 77 Gertrude kauft ihre Gartenmöbel schon seit langer Zeit bei Familie Wilhelmi, erinnert sich noch an die Zeiten zurück, in denen die nun rüstige Mutter Erna Wilhelmi, den Laden leitete. Auch wenn sie grundsätzlich lieber alle Fragen o.ä. persönlich klärt, macht ihr der Rücken schon länger einen Strich durch die Rechnung, wenn es um Unternehmungen außerhalb des Hauses geht. Das Telefonieren ist ihr eine Qual, seit ihre Schwerhörigkeit die letzten Jahre immer mehr zunahm.

Benny Knoche, 23 Benny ist einer dieser Menschen, die nicht oft das Haus verlassen. Er hält sich mit kleineren Gelegenheitsjobs über Wasser und verbringt seine restliche Zeit größtenteils vor dem Computer, um Online-Rollenspiele zu spielen. Die direkte Kommunikation mit Menschen war ihm schon immer ein Graus, was unter anderem in eine Schulzeit mündete, an die er sich nicht sehr gerne zurückerinnert. Nahezu alles was er kauft, bestellt er online, selbst seine Pizza.

##Konzept Webshop ###Funktion Webshop mit Login-System zur einfachen Verwaltung des Verkaufs bzw. der angebotenen Waren

###Umsetzung: Realisierung des Webshops mithilfe von Nodejs, Expressjs und Mongodb. Möglichst einfaches Einfügen/Verändern von Waren hat Priorität bei dem Webshop, der die gespeicherten Daten mittels Mongodb verarbeiten und serverseitig über Nodejs/Expressjs laufen soll.

##Vorgehensweise Zu Beginn der Entwicklung stand die Erstellung mehrerer Szenarien, die eine Diskussionsgrundlage für mögliche Anforderungen bildete. Diese konnten im Laufe des Prozesses mehrfach zur Evaluierung herangezogen werden. Ein darauf basierendes Exposé behandelte das Konzept eines Supportchats einer Website, das gerade in kommerziellen Umgebungen hätte zum Tragen kommen können (z.B. auf Webshops, aber auch für normale Läden, die so auf andere Art und Weise als vor Ort oder per Telefon mit Kunden in Kontakt treten konnten).
Diese Idee wurde nach einer ausgiebigen Evaluation allerdings schnell wieder fallen gelassen. Insbesondere die Kriterien des Dienstgeber/Dienstnutzer–Modells sind durch einen Support-Chat nicht erfüllt. Auch wenn eine Aufteilung einzelner Support-Anfragen z.B. in Problemkategorien oder klar einzelnen Usern zugeordnete Problem-ID’s angedacht waren, hätte eine Umsetzung trotzdem nicht die simple Input-Output-Ebene verlassen. Mit Blick auf die bereits kreierten Szenarien wurden anschließend neue Überlegungen angestellt. Ein Webshop mit dem Fokus der Überlegungen darauf, insbesondere Anwendungslogik wie Favoriten oder individualisierte Vorschläge zu implementieren, war das vorläufige Ergebnis. Anschließend wurden Informationen über in Frage kommende Datenbanksysteme für das Erfassen der Produkte herangezogen und im Hinblick auf die enorme Verbreitung und zahlreichen Möglichkeiten schließlich in Absprache mit den Gruppen-Betreuern MongoDb anstatt des vorgeschlagenen Redis ausgewählt. Simultan zu den geforderten Programmieraufgaben, die einen guten Einblick in erste Mechanismen boten, wurde nun eine Anmeldeseite basierend auf nodejs und expressjs entwickelt, die die Benutzerinformationen zunächst als json-Dateien speichert, ehe eine weitere Überarbeitung diese Informationen schließlich schon in eigene mongodb-Datenbank auslagerte.
Anschließend stand die Realisierung des Dienstgebers im Vordergrund. Im Detail wurden neben einem Anmeldungssystem und der Auslagerung der Userinformationen in eine usercollection innerhalb der mongodb-Datenbank, auch eine productscollection, sowie eine basketcollection erstellt. Innerhalb der productscollection war es nun möglich durch POST und GET Anfragen, Produkte hinzuzufügen, zu ändern, zu löschen, sowie allgemein nach Produktnamen zu suchen. Der Basket hingegen, zunächst nur rudimentär implementiert, ermöglichte es, einem festen User zugeordnet, einzelne Produkte zuzuordnen.
Basierend auf der Evaluation der Besprechung mit den Gruppenleitern, wurde die bisherige Implementation schließlich noch einmal genauer auf die REST-Tauglichkeit hin überprüft. Einer der Grundpfeiler der REST-Spezifikation ist CRUD, was sich dadurch äußert, dass das Beschaffen/Ändern etc. von Informationen, über die standardisierten HTTP-Befehle GET, PUT, POST und DELETE erfolgt. Die bisherige Implementierung allerdings verwendete zum Ändern eines Produkts innerhalb der productscollection bislang auch POST-Befehle, die durch mongodb bereitgestellte Änderungsmethoden aufriefen. Um REST-Konformität zu erreichen, wurde der Änderungsmechanismus auf PUT-Befehle umgestellt.
Ein weiteres Merkmal der REST-Architektur ist das eindeutige Identifizieren von Ressourcen durch URIs. Insbesondere die Abstraktionsebenen von Ressourcen sind hieraus ersichtlich. Um dieser Anforderung in Gänze gerecht zu werden, wurden die Ressourcen noch klarer schon innerhalb der URI voneinander differenziert und insbesondere die Verschachtelungstiefe (z.B. /products/elektronik/123) wurde einem Update unterzogen. Auch die Anforderung der statuslosen Kommunikation war in der ursprünglichen Implementierung nicht komplett erfüllt. Ursprünglich existierte eine basketcollection, in der die gewünschten Produkte referenziert werden konnten. Da ein Einkaufswagen allerdings immer nur genau einem User zugeordnet werden soll, ist es sinnvoller dies bei der Implementierung zu berücksichtigen. Nun werden die gewünschten Produkte, statt in eine eigene collection ausgelagert, auch innerhalb der usercollection abgespeichert und klar dem entsprechenden User als Array zugeordnet.
Anschließend wurden Use-Cases erstellt, anhand derer die Anforderungen an die Implementierung des anstehenden Dienstnutzers, überprüft werden können.
In der finalen Entwicklungsphase erhielt nun insbesondere die Basket-Verwaltung größere Beachtung. Produkte können nun einem für jeden Benutzer individuell zugewiesenen Basket auf der Produktübersichtsseite hinzugefügt werden.
Auch auf eine noch klare URL-Hierarchisierung wurde großer Wert gelegt, so dass nun beispielsweise die Baskets in der Struktur „products/id/basket“ abrufbar sind. Die ID’s entsprechen hier den automatisch innerhalb der mongodb angelegten.
Inzwischen herrscht zudem eine noch striktere Trennung zwischen Dienstnutzer und Dienstgeber. Der Nutzer kommuniziert über den Browser ausschließlich mit dem Dienstnutzer, der dann entsprechende Anfragen an den Dienstgeber richtet, um z.B. gewünschte Informationen aus der Datenbank zu erhalten. Der Web-Service beschäftigte sich bislang vorrangig mit den CRUD-Mechaniken, um Produkte abzufragen, zu ändern, oder ähnliches. Eine wirkliche Programmierlogik blieb dabei allerdings außen vor. Nun ist es allerdings möglich, die Produkte nach ihrer Beliebtheit zu sortieren. Indikator bzw. maßgeblicher Zähler ist hierbei das „gekauft“-Attribut eines Produktes.
Tests und das Beheben etwaiger gefundener Fehler bildeten den Abschluss dieser Entwicklungsphase.

##Fazit Die angedachten Kernelemente sind implementiert und lauffähig. Betrachtet man die Produkt- und die Nutzerverwaltung als primäre Ziele, so sind diese durch die unterschiedlichen im Web-Service verankerten CRUD-Operationen erfüllt. Auch eine Unterteilung der Rechte existiert, so dass man nur als eingeloggter Administrator Änderungen vollziehen können soll.
Wesentliche Vorgabe war es einen Service zu entwerfen, der den Ansprüchen einer REST-Architektur genügt. So sind die Ressourcen klar identifiziert über einzelne URLs, die hierarchisch aufgebaut sind. Insbesondere das Befolgen des Prinzips der Zustandslosigkeit zog im Laufe der Entwicklung einige Änderungen nach sich, da keine Zustände z.B. über Cookies gespeichert werden sollten. Als Resultat steht am Ende ein den Usern zugeordneter Basket, der als Ressource klar über eine URL ansprechbar ist.

Nichtsdestotrotz gab es auch Elemente, oder Bedenken hinsichtlich der aktuellen Implementierung, die innerhalb der vorgegebenen Zeitperiode nicht eingebaut bzw. behoben werden konnten.
Kritisch zu sehen ist in der vorliegenden Implementierung dieses Web-Service sicherlich der Sicherheitsaspekt. So existiert zwar eine Unterteilung in „normale“ Nutzer und Administratoren, doch ist der Zugang zu dem administrativen Bereich grundsätzlich für jeden Nutzer erreichbar, sofern er das entsprechende Passwort kennt.
Es existiert eine klare URL-Hierarchisierung, doch ist es ebenso möglich für Nutzer, die in der Kenntnis dieser Adressen sind, über die entsprechende URL auf Bereiche zuzugreifen, die ihnen eigentlich verwehrt sein sollten.
Auch hinsichtlich der eigentlich angestrebten Funktionalität konnte nicht jeder Plan umgesetzt werden. So ist gerade bei der Programmierlogik eine gewisse Diskrepanz zu den Zielen festzustellen. Die Produkte können zwar erfolgreich nach Beliebtheit sortiert werden, allerdings gibt es weder ein vom Warenkorb getrenntes Favoritensystem, noch ist es möglich den einzelnen Nutzern entsprechend ihrer Vorlieben Produkte vorzuschlagen („Kunden, die dies kauften, kauften auch..“).

Gerade das Zusammenspiel der zwei Server untereinander sorgte für einige Probleme, so dass viel Zeit eher der Fehlerbehebung bzw. der Übertragung einer zu Beginn nur mit einem Server getesteten Funktionalität auf zwei klar in Dienstgeber und –nutzer unterteilten Server gewidmet werden musste, als der Implementierung weiterer Logik und Funktionen.

##Arbeitsmatrix

Backend Frontend Dokumentation
Maximlian 70 50 0
Oliver 30 40 95
Yannik 0 10 5
⚠️ **GitHub.com Fallback** ⚠️