SPA mit Vue.js, vuetify, Laravel Lumen und Passport I
Teil 1: Einführung und Erstellung der Backend API mit Laravel Lumen
In dieser Tutorial-Serie auf deutsch möchte ich vorstellen, wie man eine Single Page Application “from scratch” erstellt. Wir werden uns zuerst mit der Erstellung einer API auf Datenbankbasis mit Laravel Lumen beschäftigen. Diese werden wir im zweiten Teil mit einer Authentifizierung versehen, welche durch Passport zur Verfügung gestellt wird.
Im dritten Teil beschäftigen wir uns mit dem Frontend Part. Wir werden eine neue Vue.js App anlegen, welche mit einem vue-router versehen wird und mittels axios Anfragen an die API stellt. Um alles etwas schön zu machen, werden wir vuetify in Teil 4 integrieren, um Material Komponenten im Frontend nutzen zu können. In Teil 5 werden wir schließlich die bereits vorgenommene Authentifizierung auch im Frontend übernehmen.
Was wird Inhalt der SPA sein? Wir belassen es einfach und stellen ein paar fiktive Firmen und Produkte vor. Diese kann man dann mittels Kontaktformular anfragen. Zudem wird es einen kleinen Administrationsbereich geben, in dem die bereits getätigten Kontaktanfragen ausgegeben werden können.
Wir werden den benötigten Quellcode Schritt für Schritt aufbauen und am Ende von Teil 5 per GitHub-Repository zur Verfügung stellen.
Zusammengefasst hat unser deutschsprachiges Tutorial also folgende Teile, wobei Teil 1 in diesem Artikel behandelt wird.
- Teil 1: Erstellung des Backends und der API mit Laravel Lumen
- Teil 2: Integration der Authentifizierung im Backend mit Passport
- Teil 3: Erstellung der Webanwendung mit Vue.js und axios
- Teil 4: Material Design Komponenten im Frontend durch Integration von vuetify
- Teil 5: Integration der Authentifizierung im Frontend durch Nutzung des State Handlings mit Vuex
Initialisierung von Laravel Lumen
Wir starten mit der Installation von Lumen, einem auf Laravel basierenden Framework, welches alle Voraussetzungen mit sich bringt, in kurzer Zeit eine API zu erstellen. Um Lumen installieren zu können, wird composer benötigt, welches vorher installiert werden sollte. Wir erstellen also ein neues Projekt:
composer create-project --prefer-dist laravel/lumen vue-lumen-tutorial
Erstellung des Datenbankschemas
Das mit Lumen mitgelieferte artisan-Framework bietet uns die Möglichkeit, Datenbankmigrationen vorzunehmen und die so erstellten Tabellen durch sogenannte Seeds mit Daten zu befüllen. Wir fangen also an und erstellen 2 Migrationen für eine Firmen- und eine Produkttabelle:
php artisan make:migration create_companies_table
php artisan make:migration create_products_table
Wir können nun die erstellten Dateien unter database\migrations
finden und diese bearbeiten, damit sie unseren Wünschen entsprechen. Die Firmen sollen dabei einen Namen und eine Beschreibung besitzen, die Produkte zusätzlich eine Spalte für den Fremdschlüssel auf die Firma.
Nachdem wir in der .env
unsere Datenbankverbindung hinterlegt haben, können wir die Migration ausführen
php artisan migrate
Erstellung der Models
Im nächsten Schritt kümmern wir uns um die Erstellung der Models und der Controller. Zuerst aktivieren wir Facaden und Eloquent, indem wir die dazugehörigen Zeilen in der Datei bootstrap\app.php
einkommentieren:
$app->withFacades();
$app->withEloquent();
Danach erstellen wir die eigentlichen Klassen. Leider bringt das Lumen Framework nicht die von Laravel bekannten php artisan make:controller
und php artisan make:model
. Dafür benötigen wir ein composer-Paket welches wir uns dazu installieren (dieses Paket findet auch Anwendung in Teil 2, um den APP_KEY
zu hinterlegen).
composer require flipbox/lumen-generator
Den dazugehörigen Service Provider müssen wir noch in der bootstrap\app.php
hinterlegen.
// Lumen Generator for artisan make commands
$app->register(Flipbox\LumenGenerator\LumenGeneratorServiceProvider::class);
Danach können wir die dazugehörigen Models erstellen und hinterlegen anschließend folgende Inhalte.
php artisan make:model Company
php artisan make:model Product
Wichtig zu erwähnen sind die Funktionen für die Fremdschlüsselbeziehungen in Eloquent, damit die Produkte korrekt zu den Firmen zugeordnet werden können und vice versa.
Befüllung mit Daten über Seeding
Nun wo wir die dazugehörigen Models erstellt haben, können wir im nächsten Schritt die Tabellen mittels Seeding mit Beispieldaten füllen. Dazu erstellen wir uns einen CompaniesTableSeeder
und einen ProductsTableSeeder
, wodurch Dateien im Ordner database\seeds
erstellt werden.
php artisan make:seed CompaniesTableSeeder
php artisan make:seed ProductsTableSeeder
In den erstellten Seeder-Klassen werden in der run
-Funktion die entsprechenden Elemente kreiert.
Danach werden die Seeder in der Datei database\seeds\DatabaseSeeder.php
registriert.
Zuguterletzt werden die Factory-Methoden für die einzelnen Klassen in der Datei database\factories\ModelFactory.php
eingetragen. Hier wird der Faker\Generator
eingesetzt, um sinnvolle Daten zu hinterlegen.
Ist dies alles hinterlegt, kann der Seeder über die Konsole angestoßen werden und sollte 10 Firmen und 20 korrespondierende Produkte in der Datenbank hinterlegen.
php artisan db:seed
Erstellung der Controller und der API-Endpunkte
Im nächsten Schritt widmen wir uns der Erstellung der Controller, die später mittels Routing aufgerufen werden. Ziel ist es, vorerst 4 Endpunkte zur Verfügung zu stellen:
/companies
gibt alle Firmen zurück/companies/{id}
gibt eine bestimmte Firma mit ihren Produkten zurück/products
gibt alle Produkte zurück/products/{id}
gibt ein bestimmtes Produkt zurück
Wir nutzen wieder die Bibliothek flipbox/lumen-generator
und lassen uns mit folgenden Befehlen im Ordner app\Http\Controllers
die beiden Dateien ProductController.php
und CompanyController.php
anlegen.
php artisan make:controller CompanyController
php artisan make:controller ProductController
In diesen Dateien hinterlegen wir jeweils eine showAll()
Funktion zur Rückgabe aller Elemente und eine showOne($id)
Funktion zur Rückgabe eines bestimmten Elements.
Nun erstellen wir die Routen in der Datei routes\web.php
und lassen die Endpunkte auf die jeweiligen Controller zeigen. Wir nutzen den Prefix api
für die Aufrufe, um später eventuell clustern, oder verschiedene Versionen der API anbieten zu können.
Ich habe mich vorerst dazu entschieden, nur GET-Requests zu hinterlegen. Im Rahmen von Teil 2 zur Authentifizierung kommen dann POST-Requests zum Abruf dazu. Natürlich sind auch PUT-, OPTIONS- und DELETE-Requests denkbar. Mehr ist in der Dokumentation zu finden.
Rückgabe der gewünschten Daten mittels Resourcen
Im vorerst letzten Schritt erstellen wir sogenannte Resourcen, um die Ausgabe der Elemente am Endpunkt zu steuern. Anwendungsfall ist bspw., die Zeitstempel nicht mit auszugeben oder an die Firmen schon andere Entitäten zu hängen. Dafür sind zwei Schritte nötig: erstens das Forcieren der Ausgabe im Controller, wo wir in der Funktion showOne()
die Resource um die Ausgabe wrappen (siehe jeweils Zeile 27).
Im zweiten Schritt erstellen wir dann die dazugehörigen Resourcen im Ordner app\Http\Resources
und beschränken die Ausgabe auf id
, name
und description
. Bei der einzelnen Firma geben wir zusätzlich noch die dazugehörigen Produkte - widerum als Resource - aus.
Damit sind wir mit der API-Implementierung fertig und können uns nun das Ergebnis anschauen.
Test der API mittels Postman
Dazu starten wir einfach einen PHP-Server von der Konsole aus dem Projektordner heraus:
php -S localhost:80 -t public
Dann rufen wir mittels Postman den entsprechenden Endpunkt auf. In unserem Beispiel rufen wir mittels http://localhost/api/companies/1
die Firma mit der ID 1 auf und erhalten die enstprechenden Daten mit den dazugehörigen Produkten.
Ausblick
Im nächsten Teil werden wir uns damit beschäftigen, die API mit einer Authentifizierung zu versehen. Hierfür werden wir Laravel Passport einsetzen und neue Endpunkte für ein Kontaktformular hinzufügen.