() translation by (you can also view the original English article)
Laravel und React sind zwei beliebte Web-Entwicklungstechnologien, die für den Aufbau moderner Web-Anwendungen verwendet werden. Laravel ist prominent ein serverseitiges PHP-Framework, während React eine clientseitige JavaScript-Bibliothek ist. Dieses Tutorial dient als Einführung in Laravel und React und kombiniert sie zu einer modernen Webanwendung.
Dieses Lernprogramm dient als Einführung in Laravel und React und kombiniert diese in einer modernen Webanwendung. Der Server hat eine begrenzte Aufgabe, das Back-End über einige API (Application Programming Interface) -Endpunkte zu verwalten. Der Client sendet Anforderungen an diese Endpunkte, und der Server gibt eine Antwort zurück. Erstellen Sie eine moderne Webanwendung.... Der Server kümmert sich jedoch nicht darum, wie der Client die Ansicht rendert, was im Einklang mit dem Grundsatz der Trennung von Interessen steht. Diese Architektur ermöglicht es Entwicklern, robuste Anwendungen für das Web und für verschiedene Geräte zu erstellen.
In diesem Lernprogramm verwenden wir die neueste Version von Laravel, Version 5.5, um eine REST-konforme Back-End-API zu erstellen. Das Frontend wird aus Komponenten bestehen, die in React geschrieben sind. Wir werden eine findige Produktlistenanwendung erstellen. Der erste Teil des Tutorials wird sich mehr auf die Laravel-Konzepte und das Backend konzentrieren. Lass uns anfangen.
Einführung
Laravel ist ein PHP-Framework, das für das moderne Web entwickelt wurde. Es hat eine ausdrucksstarke Syntax, die das Konvention-über-Konfiguration-Paradigma bevorzugt. Laravel verfügt über alle Funktionen, die Sie benötigen, um mit einem Projekt sofort loslegen zu können. Aber persönlich mag ich Laravel, weil es die Entwicklung mit PHP in eine völlig andere Erfahrung und einen anderen Workflow verwandelt.
Auf der anderen Seite ist React eine beliebte JavaScript-Bibliothek, die von Facebook für den Aufbau von Single-Page-Anwendungen entwickelt wurde. Mit React können Sie Ihre Ansicht in Komponenten zerlegen, in denen jede Komponente einen Teil der Benutzeroberfläche der Anwendung beschreibt. Der komponentenbasierte Ansatz hat den zusätzlichen Vorteil der Wiederverwendbarkeit und Modularität von Komponenten.
Warum Laravel und Reagieren?
Wenn Sie für das Web entwickeln, möchten Sie möglicherweise eine einzige Codebasis für den Server und den Client verwenden. Jedoch gibt nicht jedes Unternehmen dem Entwickler die Freiheit, eine Technologie seiner Wahl zu verwenden, und das aus guten Gründen. Die Verwendung eines JavaScript-Stacks für ein gesamtes Projekt ist die aktuelle Norm, aber nichts hindert Sie daran, zwei verschiedene Technologien für die Server- und die Client-Seite auszuwählen.
Wie passen Laravel und React zusammen? Ziemlich gut, in der Tat. Obwohl Laravel dies für Vue.js unterstützt hat, was ein weiteres JavaScript-Framework ist, werden wir React für das Front-End verwenden, da es beliebter ist.
Voraussetzungen
Bevor ich anfange, gehe ich davon aus, dass Sie ein grundlegendes Verständnis der RESTful-Architektur und der Funktionsweise von API-Endpunkten haben. Wenn Sie bereits Erfahrung mit React oder Laravel haben, können Sie dieses Tutorial optimal nutzen.
Wenn Sie mit beiden Frameworks jedoch noch nicht vertraut sind, machen Sie sich keine Sorgen. Das Tutorial ist aus der Perspektive eines Anfängers geschrieben, und Sie sollten in der Lage sein, ohne viel Mühe aufzuholen. Sie können den Quellcode für das Tutorial über GitHub finden.
Installieren und Einrichten Ihres Laravel-Projekts
Laravel verwendet Composer, um alle Abhängigkeiten zu verwalten. Bevor Sie also mit Laravel beginnen, laden Sie Composer auf Ihrem Computer herunter und installieren Sie ihn. Sie müssen möglicherweise auch die Pfadumgebungsvariable konfigurieren, sodass Composer global verfügbar ist.
Führen Sie den folgenden Befehl aus, um das Laravel-Installationsprogramm herunterzuladen.
1 |
composer global require "laravel/installer"
|
Wenn Sie die Variable $PATH
korrekt konfiguriert und ~/.de/poker/vendor/bin
in Ihren Pfad eingefügt haben, sollten Sie in der Lage sein, ein neues Laravel-Projekt wie folgt zu generieren:
1 |
laravel new PROJECT-NAME |
Alternativ können Sie Composer verwenden, um ein neues Projekt ohne das Laravel-Installationsprogramm zu erstellen.
1 |
composer create-project --prefer-dist laravel/laravel blog
|
Wenn alles gut geht, sollten Sie Ihre Anwendung auf einem Entwicklungsserver unter http://localhost:8000
bereitstellen können.
1 |
php artisan serve |
Hinweis: Artisan ist ein Befehlszeilentool, mit dem Sie während der Arbeit mit Laravel nicht leben können. Artisan akzeptiert eine große Liste von Befehlen, mit denen Sie Code für Ihre Anwendung generieren können. Führen Sie php
artisan list
aus, um alle verfügbaren Handwerkerbefehle anzuzeigen.
Konfigurieren der Umgebung
Ihre Anwendung wird eine .env-Datei im Stammverzeichnis enthalten. Alle umgebungsspezifischen Konfigurationsinformationen werden hier deklariert. Erstellen Sie eine Datenbank für Ihre Anwendung, falls noch nicht geschehen, und fügen Sie die Datenbankdetails in die .env-Datei ein.
1 |
DB_CONNECTION=mysql |
2 |
DB_HOST=127.0.0.1 |
3 |
DB_PORT=3306 |
4 |
DB_DATABASE=sampledb |
5 |
DB_USERNAME=root |
6 |
DB_PASSWORD= |
Modelle, Routen und Controller verstehen
Laravel ist ein Framework, das der Model-View-Controller (MVC) Architektur folgt. Grob gesagt, MVC hilft Ihnen, die Datenbankabfragen (das Modell) von der Logik zu trennen, die mit der Verarbeitung der Anforderungen (Controller) und der Darstellung des Layouts (View) zusammenhängt. Das folgende Bild zeigt die Funktionsweise einer typischen Laravel-Anwendung.



Da wir eine API mit Laravel erstellen, beschränken wir uns auf das Modell und den Controller. Wir werden unsere Optionen zum Erstellen der Ansicht im zweiten Teil dieses Tutorials überprüfen.
The Router
Wenn der Server eine HTTP-Anforderung empfängt, versucht Laravel, diese mit einer Route zu verknüpfen, die in einer der Routendateien registriert ist. Alle Routendateien befinden sich im Verzeichnis routes. routes/web.php hostet die Route für das Webinterface, während routes/api.php die Route für das API hostet. Die in api.php registrierten Routen haben das Präfix /api
(wie in localhost: 3000 / api). Wenn Sie dieses Verhalten ändern müssen, sollten Sie die RouteServiceProvider
-Klasse in /app/Providers/RouteServiceProvider.php aufrufen und dort Änderungen vornehmen.
Da wir eine Produktlistenanwendung erstellen, sind hier die Endpunkte für die API und die HTTP-Aktionen, die diesen Endpunkten zugeordnet sind.
- GET
/products/
: Abrufen aller Produkte. - GET
/product/{id}
: Abrufen des Produkts, das derid
entspricht. - POST
/products
: Erstellen Sie ein neues Produkt und fügen Sie es in die Datenbank ein. - PUT /
products/{id}
: Aktualisiert ein vorhandenes Produkt, das derid
entspricht. - DELETE
/products/{id}
: Löschen Sie das Produkt mit der angegebenenid
.
Lass uns die Terminologie richtig machen. GET, POST, PUT und DELETE sind die HTTP-Verben (im Volksmund als HTTP-Methoden bekannt), die im Wesentlichen für die Erstellung eines RESTful-Dienstes benötigt werden. /products
ist der URI, der der Produktressource zugeordnet ist. Die HTTP-Methoden fordern den Server auf, die gewünschte Aktion für eine bestimmte Ressource auszuführen.



Mit dem Router können Sie Routen für eine Ressource zusammen mit den HTTP-Methoden deklarieren, die diese Ressource als Ziel haben. Hier ist eine Beispiel-Routes-Datei, die einige hartcodierte Daten zurückgibt.
routes/api.php
1 |
/**
|
2 |
** Basic Routes for a RESTful service:
|
3 |
**
|
4 |
** Route::get($uri, $callback);
|
5 |
** Route::post($uri, $callback);
|
6 |
** Route::put($uri, $callback);
|
7 |
** Route::delete($uri, $callback);
|
8 |
**
|
9 |
**/
|
10 |
|
11 |
Route::get('products', function () { |
12 |
return response(['Product 1', 'Product 2', 'Product 3'],200); |
13 |
});
|
14 |
|
15 |
Route::get('products/{product}', function ($productId) { |
16 |
return response()->json(['productId' => "{$productId}"], 200); |
17 |
});
|
18 |
|
19 |
|
20 |
Route::post('products', function() { |
21 |
return response()->json([ |
22 |
'message' => 'Create success' |
23 |
], 201); |
24 |
});
|
25 |
|
26 |
Route::put('products/{product}', function() { |
27 |
return response()->json([ |
28 |
'message' => 'Update success' |
29 |
], 200); |
30 |
});
|
31 |
|
32 |
Route::delete('products/{product}',function() { |
33 |
return response()->json(null, 204); |
34 |
});
|
Wenn Sie überprüfen möchten, ob die Routen wie erwartet funktionieren, sollten Sie ein Tool wie POSTMAN oder curl verwenden.
Das Produktmodell
Die Produktressource benötigt ein Modell, das mit der Datenbank interagieren kann. Model ist die Ebene, die über der Datenbank liegt und alle datenbankspezifischen Begriffe versteckt. Laravel verwendet Eloquent ORM für die Modellierung der Datenbank.
Das in Laravel enthaltene Eloquent-ORM bietet eine schöne, einfache ActiveRecord-Implementierung für die Arbeit mit Ihrer Datenbank. Jede Datenbanktabelle hat ein entsprechendes "Modell", das zur Interaktion mit dieser Tabelle verwendet wird. Mit Modellen können Sie Daten in Ihren Tabellen abfragen und neue Datensätze in die Tabelle einfügen.
— Laravel Docs
Was ist mit der Definition des Datenbankschemas? Laravels Migration kümmert sich darum. Artisan verfügt über einen Migrationsbefehl, mit dem Sie Ihr Schema definieren und zu einem späteren Zeitpunkt schrittweise aktualisieren können. Erstellen Sie ein Modell und eine Migration für die Product-Entität.
1 |
$ php artisan make:model Product -m |
Hinweis: Es gibt viele Artisan-Befehle, und es ist leicht, sich zu verirren. Jeder Handwerkerbefehl enthält also einen Hilfsbildschirm, auf dem zusätzliche Informationen wie die verfügbaren Optionen und Argumente angezeigt werden. Um auf die Hilfeseite zu gelangen, sollte der Name des Befehls mit help
vorangestellt werden. Führen Sie den folgenden Hilfebefehl aus, um zu sehen, wofür die Option -m
steht: $php artisan help make:model
.
Hier ist die Migrationsdatei generiert.
database/migrations/timestamp_create_products_table.php
1 |
<?php
|
2 |
|
3 |
use Illuminate\Support\Facades\Schema; |
4 |
use Illuminate\Database\Schema\Blueprint; |
5 |
use Illuminate\Database\Migrations\Migration; |
6 |
|
7 |
class CreateProductsTable extends Migration |
8 |
{
|
9 |
|
10 |
public function up() |
11 |
{
|
12 |
Schema::create('products', function (Blueprint $table) { |
13 |
$table->increments('id'); |
14 |
$table->timestamps(); |
15 |
});
|
16 |
}
|
17 |
|
18 |
|
19 |
public function down() |
20 |
{
|
21 |
Schema::dropIfExists('products'); |
22 |
}
|
23 |
}
|
Die up
-Methode wird aufgerufen, während neue Tabellen und Spalten in die Datenbank migriert werden, während die down
-Methode beim Zurücksetzen einer Migration aufgerufen wird. Wir haben ein Schema für eine Tabelle mit drei Zeilen erstellt: id
, created_at
und updated_at
. Die Methode $table->timestamps()
ist verantwortlich für die Pflege der Spalten created_at
und updated_at
. Fügen wir der Schemadefinition noch ein paar Zeilen hinzu.
1 |
/* Let's add columns for title, description, price, availability */
|
2 |
|
3 |
public function up() |
4 |
{
|
5 |
Schema::create('products', function (Blueprint $table) { |
6 |
$table->increments('id'); |
7 |
$table->timestamps(); |
8 |
$table->string('title'); |
9 |
$table->text('description'); |
10 |
$table->integer('price'); |
11 |
$table->boolean('availability'); |
12 |
});
|
13 |
}
|
Wir haben das Schema mit vier neuen Spalten aktualisiert. Laravels Schema Builder unterstützt eine Vielzahl von Spaltentypen wie string
, text
, integer
, boolean
usw.
Um die ausstehenden Migrationen auszuführen, müssen Sie den folgenden Befehl ausführen:
1 |
php artisan migrate |
Per Konvention geht Laravel davon aus, dass das Product -Modell der Tabelle products zugeordnet ist. Wenn Sie das Modell jedoch einem benutzerdefinierten Tabellennamen zuordnen müssen, können Sie die Eigenschaft $table
verwenden, um den Namen der Tabelle zu deklarieren. Das Modell wird dann einer Tabelle namens custom_products zugeordnet.
1 |
protected $table = 'custom_products'; |
Aber wir werden die Dinge einfach halten und mit der Konvention gehen. Das generierte Produktmodell befindet sich im Verzeichnis app/. Obwohl die Modellklasse möglicherweise leer erscheint, ist sie mit verschiedenen Query Builder-Methoden ausgestattet, mit denen Sie die Datenbank abfragen können. Sie können beispielsweise Product::all()
verwenden, um alle Produkte abzurufen, oder Product::find(1)
, um ein bestimmtes Produkt mit der ID 1 abzurufen.
Laravel-Modelle verfügen über einen integrierten Schutzmechanismus gegen Massenzuverlässigkeit. Die fillable
-Eigenschaft wird verwendet, um die Attributnamen zu deklarieren, die sicher einer Masse zugewiesen werden können.
app/Product.php
1 |
/* Add the fillable property into the Product Model */
|
2 |
|
3 |
protected $fillable = ['title', 'description', 'price', 'availability']; |
Der obige Code führt die Attribute title
, description
, price
und availability
auf die Whitelist und behandelt sie als massenzuweisbar. Wir können jetzt die Product::create
-Methode verwenden, um neue Zeilen in die products-Tabelle einzufügen.
Datenbank Seeding
Mit Laravel können Sie Ihre Entwicklungs- und Produktionsdatenbank mit Dummy-Daten füllen, die Sie dann zum Testen Ihrer API-Endpunkte verwenden können. Sie können eine Seed-Klasse erstellen, indem Sie den folgenden Artisan-Befehl ausführen.
1 |
$ php artisan make:seeder ProductsTableSeeder
|
Die generierten Sämaschinen-Dateien werden im Verzeichnis database/ seeds abgelegt.
Um die Dummy-Daten zu generieren, könnten Sie etwas wie str_random(10)
verwenden, das eine zufällige Zeichenfolge zurückgibt. Wenn Sie jedoch Daten benötigen, die den tatsächlichen Daten nahe genug sind, sollten Sie etwas wie die Faker-Bibliothek verwenden. Faker ist eine Drittanbieter-Bibliothek, die mit dem Laravel-Framework zur Generierung gefälschter Daten ausgeliefert wird.
database/seeds/ProductsTableSeeder.php
1 |
use App\Product; |
2 |
|
3 |
class ProductsTableSeeder extends Seeder |
4 |
{
|
5 |
public function run() |
6 |
{
|
7 |
|
8 |
$faker = \Faker\Factory::create(); |
9 |
|
10 |
// Create 50 product records
|
11 |
for ($i = 0; $i < 50; $i++) { |
12 |
Product::create([ |
13 |
'title' => $faker->title, |
14 |
'description' => $faker->paragraph, |
15 |
'price' => $faker->randomNumber(2), |
16 |
'availability' => $faker->boolean(50) |
17 |
]);
|
18 |
}
|
19 |
}
|
20 |
}
|
Führen Sie den Befehl db:seed
artisan aus, um die Datenbank zu füllen.
1 |
$ php artisan db:seed --class=ProductsTableSeeder |
Lass uns zurück zu routes / api.php gehen und die fehlenden Teile ausfüllen.
routes/api.php
1 |
/**
|
2 |
**Basic Routes for a RESTful service:
|
3 |
**Route::get($uri, $callback);
|
4 |
**Route::post($uri, $callback);
|
5 |
**Route::put($uri, $callback);
|
6 |
**Route::delete($uri, $callback);
|
7 |
**
|
8 |
*/
|
9 |
Route::get('products', function () { |
10 |
return response(Product::all(),200); |
11 |
});
|
12 |
|
13 |
Route::get('products/{product}', function ($productId) { |
14 |
return response(Product::find($productId), 200); |
15 |
});
|
16 |
|
17 |
|
18 |
Route::post('products', function(Request $request) { |
19 |
$resp = Product::create($request->all()); |
20 |
return $resp; |
21 |
|
22 |
});
|
23 |
|
24 |
Route::put('products/{product}', function(Request $request, $productId) { |
25 |
$product = Product::findOrFail($productId); |
26 |
$product->update($request->all()); |
27 |
return $product; |
28 |
});
|
29 |
|
30 |
Route::delete('products/{product}',function($productId) { |
31 |
Product::find($productId)->delete(); |
32 |
|
33 |
return 204; |
34 |
|
35 |
});
|
Der Controller
Die Routendatei enthält derzeit die Logik für das Routing und die Bearbeitung von Anfragen. Wir können die Anforderungsbehandlungslogik in eine Controller-Klasse verschieben, sodass unser Code besser organisiert und besser lesbar ist. Lassen Sie uns zuerst eine Controller-Klasse generieren.
1 |
$ php artisan make:controller ProductsController |
Die Controller-Klasse besteht aus verschiedenen Methoden (index, show, store, update und delete), die verschiedenen HTTP-Aktionen entsprechen. Ich habe die Request-Handling-Logik von der Route zum Controller verschoben.
app/HTTP/Controllers/ProductsController.php
1 |
<?php
|
2 |
|
3 |
namespace App\Http\Controllers; |
4 |
|
5 |
use Illuminate\Http\Request; |
6 |
use App\Product; |
7 |
|
8 |
class ProductsController extends Controller |
9 |
{
|
10 |
|
11 |
public function index() |
12 |
{
|
13 |
return Product::all(); |
14 |
}
|
15 |
|
16 |
public function show(Product $product) |
17 |
{
|
18 |
return $product; |
19 |
}
|
20 |
|
21 |
public function store(Request $request) |
22 |
{
|
23 |
$product = Product::create($request->all()); |
24 |
|
25 |
return response()->json($product, 201); |
26 |
}
|
27 |
|
28 |
public function update(Request $request, Product $product) |
29 |
{
|
30 |
$product->update($request->all()); |
31 |
|
32 |
return response()->json($product, 200); |
33 |
}
|
34 |
|
35 |
public function delete(Product $product) |
36 |
{
|
37 |
$product->delete(); |
38 |
|
39 |
return response()->json(null, 204); |
40 |
}
|
41 |
|
42 |
}
|
routes/api.php
1 |
/**
|
2 |
**Basic Routes for a RESTful service:
|
3 |
**Route::get($uri, $callback);
|
4 |
**Route::post($uri, $callback);
|
5 |
**Route::put($uri, $callback);
|
6 |
**Route::delete($uri, $callback);
|
7 |
**
|
8 |
*/
|
9 |
|
10 |
|
11 |
Route::get('products', 'ProductsController@index'); |
12 |
|
13 |
Route::get('products/{product}', 'ProductsController@show'); |
14 |
|
15 |
Route::post('products','ProductsController@store'); |
16 |
|
17 |
Route::put('products/{product}','ProductsController@update'); |
18 |
|
19 |
Route::delete('products/{product}', 'ProductsController@delete'); |
20 |
|
21 |
Wenn Sie nicht bemerkt haben, habe ich eine Instanz des Produkts in die Controller-Methoden injiziert. Dies ist ein Beispiel für die implizite Bindung von Laravel. Laravel versucht, den Modellinstanznamen Product$product
mit dem URI-Segmentnamen {product}
abzugleichen. Wenn eine Übereinstimmung gefunden wird, wird eine Instanz des Produktmodells in die Controller-Aktionen eingefügt. Wenn die Datenbank kein Produkt enthält, wird ein 404-Fehler zurückgegeben. Das Endergebnis ist das gleiche wie zuvor, aber mit weniger Code.
Öffnen Sie POSTMAN und die Endpunkte für das Produkt sollten funktionieren. Stellen Sie sicher, dass der Header "Accept:application/json
" aktiviert ist.
Validierung und Ausnahmebehandlung
Wenn Sie zu einer nicht vorhandenen Ressource wechseln, werden Sie Folgendes sehen.



Die NotFoundHTTPException
ist, wie Laravel den 404-Fehler anzeigt. Wenn der Server stattdessen eine JSON-Antwort zurückgeben soll, müssen Sie das standardmäßige Verhalten bei der Ausnahmebehandlung ändern. Laravel verfügt über eine Handler-Klasse, die der Ausnahmebehandlung in der app/Exceptions/Handler.php gewidmet ist. Die Klasse hat hauptsächlich zwei Methoden: report()
und render()
. Die report
-Methode eignet sich zum Melden und Protokollieren von Ausnahmeereignissen, während die Rendermethode zum Zurückgeben einer Antwort verwendet wird, wenn eine Ausnahme auftritt. Aktualisieren Sie die Rendermethode, um eine JSON-Antwort zurückzugeben:
app/Exceptions/Handler.php
1 |
public function render($request, Exception $exception) |
2 |
{
|
3 |
|
4 |
if ($exception instanceof \Illuminate\Database\Eloquent\ModelNotFoundException) |
5 |
{
|
6 |
return response()->json([ |
7 |
'message' => 'Resource not found' |
8 |
], 404); |
9 |
}
|
10 |
|
11 |
return parent::render($request, $exception); |
12 |
}
|
Laravel ermöglicht es uns auch, die eingehenden HTTP-Anforderungen mithilfe einer Reihe von Validierungsregeln zu validieren und automatisch eine JSON-Antwort zurückzugeben, wenn die Validierung fehlgeschlagen ist. Die Logik für die Validierung wird in der Steuerung platziert. Das Illuminate\Http\Request
-Objekt stellt eine Validierungsmethode bereit, mit der wir die Validierungsregeln definieren können. Fügen wir der Speichermethode einige Validierungsprüfungen hinzu.
app/HTTP/Controllers/ProductsController.php
1 |
public function store(Request $request) |
2 |
{
|
3 |
$this->validate($request, [ |
4 |
'title' => 'required|unique:products|max:255', |
5 |
'description' => 'required', |
6 |
'price' => 'integer', |
7 |
'availability' => 'boolean', |
8 |
]);
|
9 |
$product = Product::create($request->all()); |
10 |
|
11 |
return response()->json($product, 201); |
12 |
}
|
Zusammenfassung
Wir haben jetzt eine funktionierende API für eine Produktlistanwendung. Der API fehlen jedoch grundlegende Funktionen wie Authentifizierung und Einschränkung des Zugriffs auf nicht autorisierte Benutzer. Laravel unterstützt sofort die Authentifizierung und der Aufbau einer API ist relativ einfach. Ich ermutige Sie, die Authentifizierungs-API als Übung zu implementieren.
Für diejenigen unter Ihnen, die gerade mit Laravel anfangen oder Ihr Wissen, Ihre Website oder Ihre Anwendung mit Erweiterungen erweitern möchten, haben wir eine Vielzahl von Dingen, die Sie auf Envato Market studieren können.
Jetzt, wo wir mit dem Backend fertig sind, werden wir uns auf die Front-End-Konzepte konzentrieren. Bleib dran für den zweiten Teil der Serie. Teile deine Gedanken in den Kommentaren.