16 KiB
Wonderful Weather
Laravel Projekt, welches Wetterdaten von weatherstack.com erfasst, verarbeitet und über eine API zur Verfügung stellt.
Inhaltsverzeichnis
Projektanforderungen
"Das Ziel des Tests ist es, ein Projekt zu schaffen, welches API-Daten erfasst, verarbeitet und zur Verfügung stellt. Das Projekt ist in Laravel umzusetzen. Sollten keine Laravel-Kentnisse vorliegen und die Einarbeitung als zu zeitintensiv angesehen werden ist reines PHP zu nutzen.
Anforderungen: In regelmäßigen Abständen sind Wetterdaten über die API von https://weatherstack.com (kostenlose Registrierung für API-Key nötig) über ein definiertes Set an Orte zu beziehen.
Diese Daten sind zu speichern und abrufbar zu machen über eine Webseite und eine eigene API. Dazu gehört die Suche nach Orten und die Aufbereitung der Daten wie es angemessen erscheint.
Die zu beachtende Orte sind ebenso sowohl per Webseite, als auch per API für priveligierte Nutzer zu bearbeiten.
Relevante Daten sind: Sonnenauf und -untergang; Temperatur; Windgeschwindigkeit und -richtung.
Zusatzanforderungen: Das Projekt muss aus diesem Repository heraus erstellbar und startbar sein (ein MySQL-Server kann als gegeben angesehen, oder ein sqlite-DB genutzt werden). Hierzu ist eine "Copy&Paste-Anleitung" zu erstellen, wie das Projekt mit minimalem Aufwand aufgesetzt und ausprobiert werden kann. DB-Seeder um historische Daten zu haben sind erwünscht. Das Projekt sollte über Unittests testbar sein."
Gebaut mit
Einstieg
Um die App lokal zum Laufen zu bringen, folge der kurzen Anleitung.
Voraussetzungen
Laravel Sail
Die App benutzt Laravel Sail, eine integrierte Lösung zum Ausführen eines Laravel-Projekts mit Docker. Laravel Sail ist eine Befehlszeilenschnittstelle für die Interaktion mit Laravels Standard-Docker-Konfiguration und erlaubt die Verwaltung von PHP, MySQL, Redis und vielem mehr.Docker
Docker ist ein Tool zum Ausführen von Anwendungen und Diensten in „Containern“, die die installierte Software oder Konfiguration des lokalen Computers nicht beeinträchtigt. Das bedeutet, dass wir uns keine Gedanken über die Konfiguration oder Einrichtung komplizierter Entwicklungstools wie Webserver und Datenbanken machen müssen, sondern lediglich eine funktionierende Installation von Docker benötigen.Docker Compose
Docker Compose ist ein Tool zum Definieren und Ausführen von Docker-Anwendungen mit mehreren Containern. Durch eine YAML-Datei können Dienste und Anwendungen erstellt und mit einem einzigen Befehl gestartet werden alle Dienste aus Ihrer Konfiguration.Installation
-
GIT-Repository klonen.
-
Kostenlosen API-Key von weatherstack.com besorgen und in
config/app.phpeintragen. -
Tipp: Ein Alias in der Bash Konfiguration für Sail ist sinnvoll, damit Befehle einfach per
sailausgeführt werden können:alias sail='bash vendor/bin/sail'. Ansonsten muss./vendor/bin/sailverwendet werden. Zum Anwendungsverzeichnis navigieren und folgende Befehle ausführen:cd *project-name*/ sail build --no-cache sail up -d sail artisan migrate -
Sobald die Docker-Container gestartet wurden, kann die App im Webbrowser unter http://localhost aufgerufen werden.
Features
Weboberfläche
Die Weboberfläche benutzt Laravel Views in Verbindung mit Blade Templates und bietet folgende Funktionen:
-
Orte suchen & hinzufügen: Über das Webformular können Städte hinzugefügt werden. Dabei wird ein API-Request an weatherstack.com versendet und die Antwort validiert. Die Validierung prüft, ob der eingegebene Name als Ortsname gültig ist, auf Seiten von weatherstack.com vorhanden, bereits hinzugefügt wurde oder ob das Limit für API-Anfragen aufgebraucht wurde. Falls nötig wird Ortsname außerdem aufbereitet.
-
Aktualisieren: Über den Refresh-Button können die Wetterdaten für das Set an definierten Orten aktualisiert werden.
-
Löschen: Die Löschfunktion löscht den Ort aus der Datenbank, also sowohl aus der
cityals auch aus derweather_dataTabelle (ON DELETE CASCADE).
Datenbank
Die Orts- und Wetterdaten, die ursprünglich vond er API von weatherstack.com stammen, werden in einer eigenen relationalen MariaDB-Datenbank in den Tabellen cities und weather_data gespeichert.
Tabelle cities beinhaltet folgende relevante Daten:
location_name: Name des Ortsname.location_country: Zum Ort dazugehöriges Land.
Tabelle weather_data beinhaltet folgende relevante Daten:
current_temperature: Temperatur in metrischen Einheitenweather_icon: PNG der aktuellen Wettersituationweather_description: Deskriptiver Textwind_speed: Windgeschwindigkeitwind_dir: Windrichtunglocaltime_epoch: Lokale Zeit als UNIX-Zeitstempel
Hinweis: Die geforderten Informationen zu Sonnenauf- und Untergang können nur über den historical Endpunkt von weatherstack.com abgerufen werden, für den ein erweiterter Subscription-Plan erforderlich ist (If you are currently on the Free Plan and would like to use the HTTPS API in production, please upgrade your account now.).
Task Scheduler
Das regelmäßige Abrufen von Wetterdaten wurde mittels dem Laravel Task Scheduler umgesetzt. Dazu wurde ein Schedule in App\Console\Kernel angelegt, der stündlich neue Daten für das definierte Set an Orten bezieht.
Damit der Schedule ausgelöst wird, ist ein Cron-Eintrag erforderlich. Die Docker-Umgebung von Laravel Sail hat Cron aber standardmäßig nicht installiert, weswegen das Docker-Image angepasst wurde. Dazu wurden die Dateien unter vendor\laravel\sail\runtimes\8.1 editiert und ein Cron-Job erstellt, der beim Erstellen des Docker-Images automatisch in den Container kopiert wird.
Datenbank-Seeder
Die App unterstützt das Befüllen der Datenbank mit Beispieldaten. Zum Generieren von Beispieldaten und Befüllen der Datenbank wird der Laravel Seeder in Verbindung mit Eloquent Factories und PHP Faker benutzt. Die Menge und Relationen der Daten können in Database\Seeders\CitySeeder angepasst werden.
Das folgende Beispiel löscht vorhandene Wetterdaten und ersetzt diese durch zufällig generierte Fake-Wetterdaten: sail artisan migrate:fresh --seed
API
Die Städte und ihre Wetterdaten sind über eine eigene API mit dem Endpunkt /api/city abrufbar. Der Endpunkt unterstützt die SQL-Statements GET, HEAD, POST und DELETE. Für das Hinzufügen und Bearbeiten von Datensätzen muss der JSON-Payload in raw vorliegen und über einen Accept: application/json Header verfügen. Mehr unter API.
API
Die API bietet folgende Features:
Authentisierung
Um die Anfragen an die API zu beschränken wird Laravel Sanctum in Verbindung mit Bearer-Tokens verwendet. Durch Aufrufen von /setup werden die Tokens einmalig generiert und in der Datenbank personal_access_tokens gespeichert. Bei API-Aufrufen mit Authorisierung muss der entsprechende update oder admin Token dem Request als Bearer-Token angefügt werden.
Daten abrufen
Eine Auflistung aller Orte inklusive Wetterdaten erfolgt über den Endpunkt /api/city. Über /api/city/{id} können die Ergebnisse auf einen einzelnen Ort eingeschränkt werden. Zum Abrufen von Daten wird keine Authorisierung benötigt.
GET /api/city/{id}:
{
"data": {
"id": 7,
"locationName": "Berlin",
"locationCountry": "Germany",
"weatherData": {
"data": [
{
"currentTemperature": 19,
"weatherIcon": "https://assets.weatherstack.com/images/wsymbols01_png_64/wsymbol_0004_black_low_cloud.png",
"weatherDescription": "Partly cloudy",
"windSpeed": "9",
"windDir": "WNW",
"localtimeEpoch": 1661045220
},
{
"currentTemperature": 24,
"weatherIcon": "https://assets.weatherstack.com/images/wsymbols01_png_64/wsymbol_0001_sunny.png",
"weatherDescription": "Sunny",
"windSpeed": "13",
"windDir": "N",
"localtimeEpoch": 1661093940
}
]
}
}
}
Daten filtern
Eine Einschränkung von Datensätzen kann außerdem über Filteroptionen erreicht werden. Es ist möglich, die Datensätze nach Orts- und Ländernamen zu filtern. Verfügbare Filteroptionen sind eq, lt, lte, gt und gte. Aktuell ist die Filterung für locationName und locationCountry mit dem Operator eq aktiv. Zum Filtern wird keine Authorisierung benötigt.
Beispiel zum ausschließlichen Anzeigen von Datensätzen zur Stadt Stuttgart: /api/city?locationName[eq]=Stuttgart
Daten hinzufügen
Neue Orte und dazugehörige Wetterdaten können über den Endpunkt /api/city mittels POST hinzugefügt werden. Zum Hinzufügen wird Authorisierung benötigt. Alle Felder des folgenden Request sind erforderlich. Bei Erfolg wird der neu hinzugefügte Datenbank-Datensatz zurückgesendet.
POST /api/city:
{
"locationName": "Stuttgart",
"locationCountry": "Germany",
"currentTemperature": 25,
"weatherIcon": "https://assets.weatherstack.com/images/wsymbols01_png_64/wsymbol_0001_sunny.png",
"weatherDescription": "Sunny",
"windSpeed": "4",
"windDir": "NNE",
"localtimeEpoch": 1661093940
}
Daten ändern
Vorhandene Orte und dazugehörige Wetterdaten können über den Endpunkt /api/city/{id} mittels PUT verändert werden. Da ein Ort über N Wetterdaten verfügen kann, wird nur der aktuellste Wetterdatensatz zur Stadt (höchste localtime_epoch) abgeändert. Dadurch wird gewährleistet, dass alle anderen historischen Wetterdaten zum Ort ihre Integrität bewahren. Ein eine Implementierung zum Bearbeiten von den einzelnen Wetterdaten-Datensätzen zu einer Stadt wurde aus Zeitgründen verzichtet.
Zum Bearbeiten wird Authorisierung benötigt. Alle Felder des folgenden Request sind erforderlich. Bei Erfolg wird kein Datenbank-Datensatz zurückgesendet.
Beispiel zum Verändern des Datensatzes mit der ID 0:
PUT /api/city/0
{
"locationName": "Stuttgart",
"locationCountry": "Germany",
"currentTemperature": -10,
"weatherIcon": "https://assets.weatherstack.com/images/wsymbols01_png_64/wsymbol_0001_sunny.png",
"weatherDescription": "Snowy",
"windSpeed": "4",
"windDir": "N",
"localtimeEpoch": 1661093980
}
Daten löschen
Vorhandene Orte und alle dazugehörige Wetterdaten können über den Endpunkt /api/city/{id} mittels DELETE aus der Datenbank gelöscht werden. Zum Bearbeiten wird Authorisierung benötigt. Bei Erfolg wird kein Datenbank-Datensatz zurückgesendet.
Beispiel zum Löschen des Datensatzes mit der ID 0: DELETE /api/city/0
Unit-Tests
Aus Zeitgründen sind keine Unit-Tests vorhanden (werden bei Bedarf nachgereicht).
Lizenz
Distributed under the MIT License. See LICENSE.txt for more information.
Kontakt
Marlon Maschkiwitz - zino@onlinehome.de