Update 'README.md'

This commit is contained in:
zino
2022-08-21 21:40:35 +02:00
parent 27c1969aaa
commit 1e209e9e23

371
README.md
View File

@@ -1,64 +1,347 @@
<p align="center"><a href="https://laravel.com" target="_blank"><img src="https://raw.githubusercontent.com/laravel/art/master/logo-lockup/5%20SVG/2%20CMYK/1%20Full%20Color/laravel-logolockup-cmyk-red.svg" width="400"></a></p>
<div align="center">
<img src="preview.jpg" alt="Logo">
<br /><br />
<h3 align="center">Wonderful Weather</h3>
<p align="center">
<a href="https://travis-ci.org/laravel/framework"><img src="https://travis-ci.org/laravel/framework.svg" alt="Build Status"></a>
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/dt/laravel/framework" alt="Total Downloads"></a>
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/v/laravel/framework" alt="Latest Stable Version"></a>
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/l/laravel/framework" alt="License"></a>
</p>
<p align="center">
Laravel Projekt, welches Wetterdaten von weatherstack.com erfasst, verarbeitet und über eine API zur Verfügung stellt.
<br />
</div>
<br /><br />
<!-- TABLE OF CONTENTS -->
## About Laravel
## Inhaltsverzeichnis
<ol>
<li>
<a href="#about-the-project">Projektanforderungen</a>
<ul>
<li><a href="#gebaut-mit">Gebaut mit</a></li>
</ul>
</li>
<li>
<a href="#einstieg">Einstieg</a>
<ul>
<li><a href="#voraussetzungen">Voraussetzungen</a></li>
<li><a href="#installation">Installation</a></li>
</ul>
</li>
Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experience to be truly fulfilling. Laravel takes the pain out of development by easing common tasks used in many web projects, such as:
<li>
<a href="#features">Features</a>
<ul>
<li><a href="#user-content-weboberfläche">Weboberfläche</a></li>
<li><a href="#datenbank">Datenbank</a></li>
<li><a href="#user-content-task-scheduler">Task Scheduler</a></li>
<li><a href="#datenbank-seeder">Datenbank-Seeder</a></li>
<li><a href="#api">API</a></li>
</ul>
</li>
<li>
<a href="#api">API</a>
<ul>
<li><a href="#user-content-authentisierung">Authentisierung</a></li>
<li><a href="#user-content-daten-abrufen">Daten abrufen</a></li>
<li><a href="#user-content-daten-filtern">Daten filtern</a></li>
<li><a href="#user-content-daten-hinzufügen">Daten hinzufügen</a></li>
<li><a href="#user-content-daten-ändern">Daten ändern</a></li>
<li><a href="#user-content-daten-löschen">Daten löschen</a></li>
</ul>
</li>
<li><a href="#unit-tests">Unit-Tests</a></li>
- [Simple, fast routing engine](https://laravel.com/docs/routing).
- [Powerful dependency injection container](https://laravel.com/docs/container).
- Multiple back-ends for [session](https://laravel.com/docs/session) and [cache](https://laravel.com/docs/cache) storage.
- Expressive, intuitive [database ORM](https://laravel.com/docs/eloquent).
- Database agnostic [schema migrations](https://laravel.com/docs/migrations).
- [Robust background job processing](https://laravel.com/docs/queues).
- [Real-time event broadcasting](https://laravel.com/docs/broadcasting).
Laravel is accessible, powerful, and provides tools required for large, robust applications.
## Learning Laravel
<li><a href="#lizenz">Lizenz</a></li>
<li><a href="#kontakt">Kontakt</a></li>
</ol>
Laravel has the most extensive and thorough [documentation](https://laravel.com/docs) and video tutorial library of all modern web application frameworks, making it a breeze to get started with the framework.
If you don't feel like reading, [Laracasts](https://laracasts.com) can help. Laracasts contains over 2000 video tutorials on a range of topics including Laravel, modern PHP, unit testing, and JavaScript. Boost your skills by digging into our comprehensive video library.
<br />
## Laravel Sponsors
<!-- ABOUT THE PROJECT -->
## 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.
We would like to extend our thanks to the following sponsors for funding Laravel development. If you are interested in becoming a sponsor, please visit the Laravel [Patreon page](https://patreon.com/taylorotwell).
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.
### Premium Partners
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.
- **[Vehikl](https://vehikl.com/)**
- **[Tighten Co.](https://tighten.co)**
- **[Kirschbaum Development Group](https://kirschbaumdevelopment.com)**
- **[64 Robots](https://64robots.com)**
- **[Cubet Techno Labs](https://cubettech.com)**
- **[Cyber-Duck](https://cyber-duck.co.uk)**
- **[Many](https://www.many.co.uk)**
- **[Webdock, Fast VPS Hosting](https://www.webdock.io/en)**
- **[DevSquad](https://devsquad.com)**
- **[Curotec](https://www.curotec.com/services/technologies/laravel/)**
- **[OP.GG](https://op.gg)**
- **[WebReinvent](https://webreinvent.com/?utm_source=laravel&utm_medium=github&utm_campaign=patreon-sponsors)**
- **[Lendio](https://lendio.com)**
Die zu beachtende Orte sind ebenso sowohl per Webseite, als auch per API für priveligierte Nutzer zu bearbeiten.
## Contributing
Relevante Daten sind: Sonnenauf und -untergang; Temperatur; Windgeschwindigkeit und -richtung.
Thank you for considering contributing to the Laravel framework! The contribution guide can be found in the [Laravel documentation](https://laravel.com/docs/contributions).
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."
## Code of Conduct
<br />
In order to ensure that the Laravel community is welcoming to all, please review and abide by the [Code of Conduct](https://laravel.com/docs/contributions#code-of-conduct).
### Gebaut mit
* [![Laravel][Laravel.com]][Laravel-url]
* [![Bootstrap][Bootstrap.com]][Bootstrap-url]
## Security Vulnerabilities
<br />
If you discover a security vulnerability within Laravel, please send an e-mail to Taylor Otwell via [taylor@laravel.com](mailto:taylor@laravel.com). All security vulnerabilities will be promptly addressed.
<!-- GETTING STARTED -->
## Einstieg
## License
Um die App lokal zum Laufen zu bringen, folge der kurzen Anleitung.
The Laravel framework is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT).
### Voraussetzungen
<details>
<summary>Laravel Sail</summary>
Die App benutzt <a href="https://laravel.com/docs/9.x/sail" target="_blank">Laravel Sail</a>, 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.
</details>
<details>
<summary>Docker</summary>
<a href="https://laravel.com/docs/9.x/sail" target="_blank">Docker</a> 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.
</details>
<details>
<summary>Docker Compose</summary>
<a href="https://docs.docker.com/compose/install/" target="_blank">Docker Compose</a> 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.
</details>
<br />
### Installation
1. GIT-Repository klonen.
2. Kostenlosen API-Key von [weatherstack.com](https://weatherstack.com/) besorgen und in `config/app.php` eintragen.
3. Tipp: Ein Alias in der Bash Konfiguration für Sail ist sinnvoll, damit Befehle einfach per `sail` ausgeführt werden können: `alias sail='bash vendor/bin/sail'`. Ansonsten muss `./vendor/bin/sail` verwendet werden. Zum Anwendungsverzeichnis navigieren und folgende Befehle ausführen:
```sh
cd *project-name*/
sail build --no-cache
sail up -d
sail artisan migrate
```
4. Sobald die Docker-Container gestartet wurden, kann die App im Webbrowser unter http://localhost aufgerufen werden.
<br />
<!-- USAGE EXAMPLES -->
## Features
#### Weboberfläche
Die Weboberfläche benutzt [Laravel Views](https://laravel.com/docs/9.x/views) in Verbindung mit [Blade Templates](https://laravel.com/docs/9.x/blade) 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 `city` als auch aus der `weather_data` Tabelle (`ON DELETE CASCADE`).
<br />
#### 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 Einheiten
* `weather_icon`: PNG der aktuellen Wettersituation
* `weather_description`: Deskriptiver Text
* `wind_speed`: Windgeschwindigkeit
* `wind_dir`: Windrichtung
* `localtime_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.`).
<br />
#### Task Scheduler
Das regelmäßige Abrufen von Wetterdaten wurde mittels dem Laravel [Task Scheduler](https://laravel.com/docs/9.x/scheduling) 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](https://www.linux.org/docs/man8/cron.html) 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.
<br />
#### 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](https://laravel.com/docs/9.x/seeding) in Verbindung mit [Eloquent Factories](https://laravel.com/docs/9.x/eloquent-factories) und [PHP Faker](https://github.com/fzaninotto/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.
<br />
## API
Die API bietet folgende Features:
<br />
###### Authentisierung
Um die Anfragen an die API zu beschränken wird [Laravel Sanctum](https://laravel.com/docs/9.x/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.
<br />
###### 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}`:
```json
{
"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
}
]
}
}
}
```
<br />
###### 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`
<br />
###### 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`:
```json
{
"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
}
```
<br />
###### 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`
```json
{
"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
}
```
<br />
###### 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`
<br />
#### Unit-Tests
Aus Zeitgründen sind keine Unit-Tests vorhanden (werden bei Bedarf nachgereicht).
<br />
<!-- LICENSE -->
## Lizenz
Distributed under the MIT License. See `LICENSE.txt` for more information.
<br />
<!-- CONTACT -->
## Kontakt
Marlon Maschkiwitz - zino@onlinehome.de
<!-- MARKDOWN LINKS & IMAGES -->
<!-- https://www.markdownguide.org/basic-syntax/#reference-style-links -->
[contributors-shield]: https://img.shields.io/github/contributors/github_username/repo_name.svg?style=for-the-badge
[contributors-url]: https://github.com/github_username/repo_name/graphs/contributors
[forks-shield]: https://img.shields.io/github/forks/github_username/repo_name.svg?style=for-the-badge
[forks-url]: https://github.com/github_username/repo_name/network/members
[stars-shield]: https://img.shields.io/github/stars/github_username/repo_name.svg?style=for-the-badge
[stars-url]: https://github.com/github_username/repo_name/stargazers
[issues-shield]: https://img.shields.io/github/issues/github_username/repo_name.svg?style=for-the-badge
[issues-url]: https://github.com/github_username/repo_name/issues
[license-shield]: https://img.shields.io/github/license/github_username/repo_name.svg?style=for-the-badge
[license-url]: https://github.com/github_username/repo_name/blob/master/LICENSE.txt
[linkedin-shield]: https://img.shields.io/badge/-LinkedIn-black.svg?style=for-the-badge&logo=linkedin&colorB=555
[linkedin-url]: https://linkedin.com/in/linkedin_username
[product-screenshot]: images/screenshot.png
[Next.js]: https://img.shields.io/badge/next.js-000000?style=for-the-badge&logo=nextdotjs&logoColor=white
[Next-url]: https://nextjs.org/
[React.js]: https://img.shields.io/badge/React-20232A?style=for-the-badge&logo=react&logoColor=61DAFB
[React-url]: https://reactjs.org/
[Vue.js]: https://img.shields.io/badge/Vue.js-35495E?style=for-the-badge&logo=vuedotjs&logoColor=4FC08D
[Vue-url]: https://vuejs.org/
[Angular.io]: https://img.shields.io/badge/Angular-DD0031?style=for-the-badge&logo=angular&logoColor=white
[Angular-url]: https://angular.io/
[Svelte.dev]: https://img.shields.io/badge/Svelte-4A4A55?style=for-the-badge&logo=svelte&logoColor=FF3E00
[Svelte-url]: https://svelte.dev/
[Laravel.com]: https://img.shields.io/badge/Laravel-FF2D20?style=for-the-badge&logo=laravel&logoColor=white
[Laravel-url]: https://laravel.com
[Bootstrap.com]: https://img.shields.io/badge/Bootstrap-563D7C?style=for-the-badge&logo=bootstrap&logoColor=white
[Bootstrap-url]: https://getbootstrap.com
[JQuery.com]: https://img.shields.io/badge/jQuery-0769AD?style=for-the-badge&logo=jquery&logoColor=white
[JQuery-url]: https://jquery.com