Skip to content

flohop/holiday-challenge

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

75 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

☀️check24-holiday-challenge☀️

Server Specs
- Tier: Value
- 1 vCore
- 2GB RAM
- 40 GB SSD NVMe
- bis zu 250 Mbit/s   

Intro

Vielen Dank, dass sie mein Projekt für das Check24 CodeDev Scholarship in Betracht ziehen.

Es war hat viel Spaß gemacht, an diesem Projekt zu arbeiten und dabei eine Menge zu lernen. Da ich zum ersten Mal mit so einem großen Datensatz arbeitete, konnte ich meine Kenntnisse in diesen Bereich imens erweitert.

Das Projekt zielt darauf ab, die Wartezeit für Benutzer zu minimieren und ihnen ein reibungsloses Nutzungserlebnis zu bieten. In dieser README-Datei werden nicht nur die Schritte zum Ausführen des Projekts erklärt, sondern auch alle Optimierungen, die implementiert wurden, um die Leistung zu verbessern. Im Abschluss werden noch mögliche Verbesserungen betrachtet, die implementiert werden sollten, wenn man das Projekt veröffentlichen wollen würde.

Lokal ausführen

Docker

Dank der mitgelieferten docker-compose.yaml Datei ist die lokale ausführung sehr reibungslos.

  1. docker compose build
  2. docker compose up

Danach sollten folgende Docker container gestartet werden:

  • ExpressJs backend auf port 4000
  • ReactJs frontend auf port 3000

Da der Import der Daten sehr lange dauert, wird eine MongoDb Instanz gehostet. Bitte führen sie keine automatisierten Tests durch, die die Serverkosten unnötig in die Höhe treiben würden.

Da jedoch der Import der Daten sehr lange dauert, ist auch eine Live Website bereit gestellt, wo die Anwendung genutzt werden kann. Die Ladegeschwindigkeiten sind hier langsamer als bei der lokalen Ausführung, da der gemietete Server geringere Specs hat als die meisten Arbeitslaptops.

Um einen besseren Überblick über die Laufzeit zu erhalten, können Sie das mit abgegebene Video betrachten, wo das Projekt vorgestellt wird.

Backend

ExpressJs GraphQL MongoDB

Für das Backend wurde ExpressJs mit Typescript verwendet.
Ich habe mich aufgrund des geringen performance overheads für ExpressJs entschieden.

Kombiniert wurde das mit GraphQL um die API möglichst typesafe zu machen. Außerdem kann dadurch der Client entscheiden welche Attribute er vom Server benötigt. Dies wurde für diese Anwendung zwar nicht sehr häufig verwendet, jedoch kann dies bei einer möglichen Weiterentwicklung der Seite nützlich sein.

Es wurde sich für MongoDb anstatt einer SQL Datenbank entschieden, da es in diesem Projekt nur 2 Objektetypen gibt und eine relationale Datenbank dadurch zu viel overhead hätte und damit eine potentiell geringere Lesezeit

Optimierungen:

Der Server wurde entwickelt mit Fokus auf Geschwindigkeit. Dafür wurden mehrere an Technicken verwendet, die wichtigsten werden hier gelistet zusammen mit dem Drawback der dadurch entsteht.

Covered Query
🟢 Signifikant schnellere Lesegeschwindigkeit

🔴 Größere Datenbankgröße
🔴 Langsamere Schreibleistung (für dieses Projekt nicht relevant, da keine neuen Angebote erstellt werden)
🔴 Längeres Setup. Das Erstellen der Indizes dauert eine beträchtliche Zeit.

Bei allen Queries wurde darauf geachtet, dass für diese ein Index existiert. Dadurch kann dieser geprüft werden 
und die 100 Millionen Dokumente müssen nicht durchsucht werden. Dies hat eine signifikante Verbesserung der Lesegeschwindigkeit zur Folge.
Optimisierte Queries
🟢 Schnellere Lesegeschwindigkeit

Die einzelnen Schritte der aggregate Funktion sind angeordnet um die Lesezeit zu minimieren.
So wird erst nach initialem Filtern die Länge des Urlaubs berechnet (duration), um das an möglichst wenig Dokumenten machen zu müssen.
Hotels In-Memory speichern
🟢 Konstante Zugriffszeit

🔴 Nicht skalierbar für Millionen von Hotels

Die Hotels werden nicht aus der MongoDb Datenbank ausgelesen, sondern aus einer Liste.
Die Liste wird zu Beginn des Servers initialisiert indem die Hotels aus einer JSON Datei geladen werden.
Dadurch muss dafür nie auf die MongoDb Datenbank zugegriffen werden, was zu einer sehr schnellen Lesezeit für die Hotels führt
Pagination

🟢 Weniger Dokumente auslesen

🟢 Weniger Dokumente werden übertragen

Um nicht alle gefundenen Hotels auf einmal auszulesen und dem Nutzer zu senden, wird Pagination verwendet. Dadurch kann im Frontend ein Infinite-Scroll implementiert werden.

Frontend

React NextJs GraphQL

Für das Frontend wurde das zur Verfügung gestellte Projekt mit NextJs (React) und Typescript verwendet und erweitert.

Infinite Scroll

🟢 Geringere Wartezeiten

Dank der Pagination im Backend, kann nur ein Subset von alle Angeboten & Hotels geladen werden. Sobald der Nutzer beim Scrollen eine bestimmte Grenze erreicht hat, werden weitere Angebote bzw. Hotels geladen. Indem die Anzahl der geladenen Objekte / des loading thresholds optimiert wird, kann man die Illusion wahren, dass alle Objekte in so kurzer Zeit geladen wurden.

Zusätzliche Filter

🟢 Genauerer Filter sorgt für weniger Angebote und schnellere Lesezeit

🔴 Nutzer muss mehr Eingabefelder ausfüllen

Indem zusätzliche zu den vorausgesetzen Filter nach roomtype, mealtype, price & oceanview gefiltered wird, kann eine schnellere Datenbankanfrage erzielt werden.

zukünftige Verbesserungen

In diesem Projekt wurden einige best practices vernachlässigt, die für eine production Anwendung noch nötig wären. Diese sollen in dieser Sektion aufgelistet werden und kurz erwähnt werden, warum sie nötig sind.

SSL Encryption
Momentan ist die Kommunikation mit der Website nicht verschlüsselt und läuft über http.
Diese Verbindung müsste noch mit einem Service with *Let's Encrypt* zu https gebracht werden.
CI/CD Pipeline
Momentan muss bei Veränderung des Codes, dieser manuell gebuilded, auf dem Server gecloned und docker compose neu 
ausgeführt werden. Dies sollte automatisiert werden und der build code nicht mehr auf GitHub hochgeladen werden.
Außerdem sollte in Zuge dessen das Projekt eine Test pipeline durchlaufen.
Tests
Momentan wurden keine Tests geschrieben um die Funktionalitäten des Projekts zu prüfen.
Dies wäre noch unabdinglich, wenn man das Projekt weiter entwickeln und skalieren wollte.
Mehr Type safety
Obwohl Typescript verwendet wurde, wurde oft der `any` type verwendet, um die Entwicklung zu beschleunigen.
Da dies jedoch auf Lange sich die Entwicklung potentiell verlangsamt, wäre es noch wichtig, Typescript im vollen Umfang 
im Projekt zu verwenden.

Outro

Ich hoffe ich konnte mit diesem Projekt aussagekräftig demonstrieren, warum ich für das Stipendium geeignet bin. Bei weiteren Fragen zum Projekt stehe ich jederzeit sehr gerne zur Verfügung: hoppe.florian02@gmail.com

Um mehr über mich zu erfahren, besuchen sie gerne meine:

About

My project for the Check24 Holiday Challenge

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages