Dieses Repository repräsentiert die Software-Komponente von Jonas Siggelkow für das Portfolio im Modul Web-Programmierung und verteilte Systeme.
Die Komponente ist ein Teil des Projekts "Twitter".
Für die Umsetzung der Komponente gab es vier Grundanforderungen.
Um diese Grundanforderungen umzusetzen mussten weitere Anforderungen definiert werden, damit die Komponente alleinstehend funktioniert.
- Als User möchte ich Posts liken können, damit ich ausdrücken kann, ob mir ein Post gefällt oder nicht.
- Als User möchte ich andere Posts kommentieren können, damit ich meine Meinung zu anderen Posts abgeben kann.
- Als User möchte ich andere Posts reposten können, damit ich Posts verbreiten kann.
- Als User möchte ich Posts speichern können, damit ich mir diese nochmal gesammelt anzeigen lassen kann.
- Als User möchte ich Posts senden können, damit anderen Usern meine Posts angezeigt werden.
- Als User möchte ich die Anzahl der Likes, Kommentare und Retweets eines Posts sehen können, damit ich einen Überblick habe wie der Post insgesamt bei andern Usern angekommen ist.
- Als User möchte ich Posts angezeigt bekommen, damit ich sehen kann, was andere User gepostet haben.
- Als User möchte ich Kommentare eines Posts sehen, damit ich lesen kann, was andere User zu einem Post kommentieren.
- Als User möchte ich mir einen Account erstellen, damit die Aktivitäten in der Komponente an meine Benutzer-Entität geknüpft sind.
- Als User möchte ich mich anmelden können, damit ich einen Zugang zum System habe.
- Es müssen keine Bilder, Videos o.ä hochgeladen werden können.
- Posts, Kommentare und Zitate müssen nicht gelöscht oder bearbeitet werden können.
- Es muss kein professioneller Login / Signup erstellt werden.
- Es müssen keine Benutzereinstellungen (z.B. Username oder Profilbild ändern) implementiert werden.
- Es muss keine Feed-Strategie (Algorithmus) entwickelt werden, die steuert wie und welche Posts angezeigt werden.
- Die Komponente muss weder deployed noch gehostet werden.
Für die Erstellung der Komponente wurde sich so weit es geht an die vorgegebenen Technologien, Frameworks und Bibliotheken aus dem ACD orientiert.
Aus Kosten- und Komplexitätsgründen gibt es jedoch teilweise Abweichungen:
- Spring Boot für das Backend
- Angular für das Frontend
- Docker
- Flyway
- PrimeNG statt Angular Material
- PostgreSQL statt Oracle Database
- TailwindCSS
git clone https://github.com/JSiggelkow/Twitter.git
Um die Architektur des ACD möglichst genau nachzubilden, wird die Anwendung in Docker-Containern ausgeführt.
Für die lokale Installation ist also eine funktionierende Docker-Installation erforderlich.
Docker Installation
Es gilt als Best Practice, keine Passwörter oder Secrets in Git zu versionieren.
Für die lokale Installation müssen jedoch ein Datenbank-Passwort und ein Secret Key erstellt werden.
Für die lokale Installation müssen diese Werte als Umgebungsvariablen gesetzt werden.
cd twitter/twitterBackend
mkdir secrets
echo "Password" > db_password.txt
NOTE: Hier sollte ein eigenes, starkes Password verwendet werden!
Benutzerinteraktionen werden serverseitig authentifiziert, um Sicherheitsrisiken durch manipulierte Frontend-Daten zu verhindern. Die Nutzeridentität wird über JWT-Token geprüft, wobei ein Secret Key als Umgebungsvariable gesetzt werden muss.
echo "Secret Key" > jwt_key.txt
Ein solcher Key lässt sich z.B. ganz einfach mit node erstellen oder über https://jwtsecret.com/generate
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
Über die compose.yaml (im twitter directory) können nun der Backend-, Frontend- und Datenbank-Container gestartet werden:
docker compose up
NOTE: docker compose up -d um die Container im Hintergrund zu starten :)
Das Backend und Frontend der Anwendung folgen einer klar definierten Struktur, um Konsistenz, Übersichtlichkeit und Erweiterbarkeit sicherzustellen.
Im Folgenden wird die Struktur der Anwendung näher erläutert.
Das Spring Boot-Backend ist in verschiedene Schichten modular unterteilt. Dies dient der Skalierbarkeit, Testbarkeit und einer klaren Trennung der Verantwortlichkeiten.
Die Datenschicht umfasst alle Elemente, die für die Manipulation von Daten zuständig sind. Sie bildet die Grundlage der gesamten Anwendung und umfasst:
- Entitäten: Repräsentieren die Datenstrukturen und beschreiben die Speicherung in der Datenbank.
- Repositories: Bieten Zugriff auf die Datenbank durch CRUD-Operationen (Create, Read, Update, Delete).
- Mapper: Verantwortlich für die Konvertierung zwischen Entitäten und DTOs, um Daten sauber zwischen den Schichten zu übertragen.
Die Logikschicht implementiert die zentrale Business-Logik. Sie fungiert als Vermittler zwischen der Datenschicht und der Controllerschicht.
- Services: Bieten Methoden an, die die eigentliche Geschäftslogik bereitstellen. Sie greifen auf die Repositories der Datenschicht zu und sorgen für die Verarbeitung von Daten.
- Exceptions: Stellen individuelle, anwendungsspezifische Fehler dar.
Die Controllerschicht ist die Schnittstelle zwischen dem Backend und dem Frontend. Innerhalb dieser Schicht werden HTTP-Anfragen vom Frontend verarbeitet.
- Controller: Bereitstellung von Endpunkten für die Kommunikation mit dem Frontend. Sie nehmen Anfragen entgegen, validieren diese und nutzen Methoden der Serviceschicht.
- DTOs: Sollen die Daten für das Frontend bündeln und auf das Wesentliche reduzieren, um die Effizienz und Performance zu steigern, indem unnötiger Datenverkehr vermieden wird.
Der Bereich Security ist vollständig von der Business-Logik entkoppelt und umfasst die Authentifizierung und Autorisierung der Anwendung. Dies schafft die Flexibilität die gesamte Sicherheitsschicht schnell und unkompliziert durch die eigentliche Sicherheitskomponente (von Tizian) ersetzen zu können.
- Security
Das Config-Package enthält allgemeine Konfigurationen für das gesamte Projekt. Diese dienen zur einfachen Anpassung und Modularisierung der Anwendung.
- Config
Das Frontend ist ebenfalls in logische Schichten unterteilt, um Übersichtlichkeit, Lesbarkeit und Wartbarkeit zu gewährleisten.
Dieses Package enthält alle benötigten Components. Dabei wird zwischen Site Components und Shared Components unterschieden:
- Site Components: Components, die einzelne Seiten oder Bereiche der Anwendung repräsentieren, z. B. Login, Signup, Feed, Profile, Menu usw.
- Shared Components: Components, die wiederverwendbar sind und in der gesamten Anwendung genutzt werden, z. B. Post, Tweet, Quote usw.
Jeder Component besteht aus einer HTML- und CSS-Datei (View) sowie einer TypeScript-Datei (Controller).
Dieses Package enthält einen Route-Guard, der sicherstellt, dass nur authentifizierte Benutzer den Hauptbereich der Anwendung betreten können. Nicht authentifizierte Nutzer werden zum Login weitergeleitet.
Hier sind verschiedene Interfaces definiert, die die DTOs (Data Transfer Objects) aus dem Backend repräsentieren. Diese Interfaces sind essenziell für die Kommunikation mit der REST-API.
Die Services enthalten Funktionen die componentübergreifend genutzt werden können. Außerdem sind in diese Services die gesamten REST-Schnittstellen zum Backend ausgelagert. Beispiele sind:
- AuthService: Verarbeitung von Authentifizierungsvorgängen
- FeedService: Datenhandling für den Feed
- TweetService: Verwaltung von Tweets
Methoden werden so zentral definiert und können anschließend in mehreren Komponenten wiederverwendet werden.
Obwohl aus dem ACD die Nutzung einer Oracle Database hervorgeht, wurde sich aus Kostengründen für die Erstellung des Prototyps für eine PostgreSQL Datenbanklösung entschieden.
Um Datenbankänderungen und Versionen transparent zu gestalten wurde außerdem Flyway für die Datenbankmigration genutzt.
Vor der Erstellung der Datenbank wurde eine Entity Relationship Modell erstellt um die Entitäten und Abhängigkeiten darzustellen.
Für die Erstellung des Entity Relationship Modells wurde als erstes Twitter analysiert. Hierbei ist aufgefallen, dass Twitter hauptsächliche zwei Entitäten hat: User und Post
Alle anderen "Objekte" wie Retweet, Quote, Comment sind auch im Allgemeinen normale Posts.
Auf Grundlage des Entity Relationship Modells wurde anschließend ein Relationenmodell erstellt.
Dieses wurde dann normalisiert, sodass fünf verschiedene Tabellen erstellt werden: Users, Post, Retweet, Save, PostLikes:
Da diese Komponente nur einen Teil des gesamten Projekts darstellt, wurde darauf geachtet, dass sie modular aufgebaut ist. Die Schnittstellen zu anderen Komponenten sind klar definiert, sodass diese problemlos integriert und erweitert werden können.
Die gesamte Komponente läuft als eigenständiger Docker-Container, was die Zusammenarbeit im Team sowie die Modularität erheblich erleichtert. Dadurch können Änderungen im Team effizient umgesetzt und die Komponente reibungslos in das Gesamtprojekt eingebettet werden.
Derzeit existiert ein "Placeholder"-Login- und Signup-System, das sowohl im Frontend als auch im Backend klar von der restlichen Komponente getrennt ist. Diese Modularität ermöglicht die unkomplizierte Integration des endgültigen Login- und Signup-Systems von Tizian.
Es existiert bereits ein Template für die Route sowie die Profil-Komponente, die problemlos durch Nathans User-Settings-Komponente ersetzt werden können. Außerdem wurde im Frontend und Backend ein modularer UserService implementiert, der schnell und einfach erweitert werden kann.
Die Icons für "Fotos hinzufügen" und "Videos hinzufügen" wurden bereits in die Benutzeroberfläche integriert. Die entsprechende Logik kann mühelos über den bestehenden TweetService implementiert werden, wodurch die Erweiterung nahtlos erfolgen kann.