1. Was werden wir tun?

Im folgenden Tutorial erläutere ich, wie du mit relativ wenig Aufwand eine moderne Web App realisieren kannst, die jederzeit flexibel erweitert werden kann.

Das Projekt wird ein Backend und ein Frontend beinhalten:

  • Das Backend werden wir in PHP schreiben – ich demonstriere das Vorgehen in diesem Tutorial an dem Framework Laravel. Es hat den Vorteil, dass wir in kurzer Zeit eine API aufbauen können, mit der wir arbeiten werden. Außerdem bringt es seine eigene Template-Engine mit, die wir für unser Frontend benutzen können.
  • Im Frontend benutzen wir die JavaScript-Bibliothek JQuery. Mit JQuery übermitteln wir HTTP-Requests an das Backend, das uns die angeforderten Daten zurückliefert. Anschließend stellen wir die Daten mit JQuery im HTML-Template dar.

Das Vorgehen lässt sich mit jeder REST-API umsetzen. Du kannst durchaus auch direkt zu Teil 3 übergehen, wenn du eine eigene API baust oder bereits eine existiert.

Alternativ findest du meinen Code aus diesem Tutorial auch hier: https://github.com/nfandrich/dynamic-web-app


2. Erstellen des Backends

2.1 PHP Package Manager Composer installieren

Um das Vorhaben Zeiteffizient umzusetzen, widmen wir uns zunächst der Erstellung des Backends. Um ein Laravel-Projekt erstellen zu können, benötigen wir den PHP Package Manager Composer. Ladet ihn kostenlos unter https://getcomposer.org/ herunter und installiert ihn.

2.2 Laravel-Framework installieren

Da Laravel lediglich ein Composer-Package ist, müssen wir dieses Package zunächst herunterladen. Dafür führst du folgenden Befehl in der Konsole aus:

composer global require laravel/installer

Ist Laravel installiert, kannst du mit folgendem Befehl ein neues Projekt erstellen:

laravel new web-app

Du kannst statt „web-app“ einen beliebigen Projektnamen auswählen. Damit ist die Installation abgeschlossen und wir können zur Einrichtung übergehen.

2.3 Laravel-Projekt einrichten

Richte das Projekt zunächst erst einmal nur soweit ein, dass im Browser die Demoseite aufgerufen werden kann (welche von Laravel automatisch erstellt wurde unter: web-app\resources\views).

Richte dazu cdeinen lokalen Webserver ein (ich benutze das Programm XAMPP), und lass den Webserver auf das Verzeichnis „public“ deines Laravel-Projektes zeigen.

Rufst du nun im Browser http://localhost auf, solltest du die Demoseite von Laraval sehen.

2.4 Controller, Model, Migration und Seed anlegen

Ich setze einfach mal voraus, dass du diese Begriffe kennst bzw. in der Lage bist, diese Komponenten zu recherchieren. Alle notwendigen Informationen kannst du in der Laravel-Dokumentation nachschlagen.

Die Schritte zur Erstellung in Kürze:

  1. Erstelle ein Model mit dem Namen Grocery (php artisan make:model Grocery)
  2. Erstelle einen Controller mit dem Namen GroceryController (php artisan make:controller GroceryController)
  3. Erstelle eine Migration mit dem Namen create_groceries_tables (php artisan make:migration create_groceries_table)
  4. Erstelle einen Seed mit dem Namen GroceriesSeeder (php artisan make:seed GroceriesSeeder)
  5. Füge der Migration folgenden Code hinzu:
    public function up()
    {
       Schema::create('groceries', function (Blueprint $table) {
         $table->bigIncrements('id');
         $table->string('title');
         $table->string('category');
         $table->timestamps();
      });
    }
  6. Füge dem Seed folgenden Code hinzu:
    public function run()
    {
      DB::table('groceries')->delete();
      DB::table('groceries')->insert([
        'title' => 'Apfel',
        'category' => 'Obst',
        'created_at' => date("Y-m-d H:i:s"),
        'updated_at' => date("Y-m-d H:i:s")
      ]);
      DB::table('groceries')->insert([
        'title' => 'Banane',
        'category' => 'Obst',
        'created_at' => date("Y-m-d H:i:s"),
        'updated_at' => date("Y-m-d H:i:s")
      ]);
      DB::table('groceries')->insert([
        'title' => 'Orange',
        'category' => 'Obst',
        'created_at' => date("Y-m-d H:i:s"),
        'updated_at' => date("Y-m-d H:i:s")
      ]);
      DB::table('groceries')->insert([
        'title' => 'Möhre',
        'category' => 'Gemüse',
        'created_at' => date("Y-m-d H:i:s"),
        'updated_at' => date("Y-m-d H:i:s")
      ]);
      DB::table('groceries')->insert([
        'title' => 'Brokkoli',
        'category' => 'Gemüse',
        'created_at' => date("Y-m-d H:i:s"),
        'updated_at' => date("Y-m-d H:i:s")
      ]);
      DB::table('groceries')->insert([
        'title' => 'Gurke',
        'category' => 'Gemüse',
        'created_at' => date("Y-m-d H:i:s"),
        'updated_at' => date("Y-m-d H:i:s")
      ]);
    }
  7. Füge der Datei „DatabaseSeeder.php“ folgende Zeile hinzu:
    $this→call(GroceriesSeeder::class);
2.5 Datenbank erstellen und der .env-Datei hinzufügen

Rufe deine lokale Datenbanksoftware auf (zumeist phpmyadmin, auch bei XAMPP). Erstelle die Datenbank web-app.

Damit unser Projekt eine Verbindung mit dieser Datenbank aufbauen kann, tragen wir sie in der .env-Datei ein.

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=web-app
DB_USERNAME=root
DB_PASSWORD=root

Benutzer und Passwort lauten in meinem Fall beide „root“, das ist standardmäßig in phpmyadmin so. Gerne kannst du aber auch einen eigenen Datenbank-Benutzer erstellen oder das root-Passwort ändern. Da wir lokal arbeiten, darf es aber auch gerne unverändert bleiben.

2.6 Daten in Datenbank überführen

Lass uns nun die Datenbank mit Daten füllen. Zunächst mit der Tabelle (siehe Migration) und danach mit Testdaten (siehe Seed). Hierfür gibt es wieder einen Konsolenbefehle, der beides gleichzeitig durchführt:

php artisan migrate --seed

Der Vorgang war erfolgreich, wenn sich in der Datenbank nun die Tabelle sowie die Testdaten befinden.

2.7 Controller erweitern

Bislang ist der GroceryController noch leer. Das ändern wir nun, indem wir eine Methode hinzufügen, die alle Lebensmittel aus der groceries-Tabelle lädt.

Oberhalb der Klasse fügst du die Zeile „use App\Grocery;“. Das ist das Model, über das die Kommunikation mit der Datenbank stattfinden wird. Im Anschluss erstellst du folgende Methode im Controller:

public function index() {
// Laden aller Spalten, absteigende Sortierung anhand der Spalte 'id'
$groceries = Grocery::orderBy('id', 'desc')->get();

// Rückgabe im JSON-Format
return response()->json($groceries);
}
2.8 App-Routing hinzufügen

Jetzt existieren eine Datenbank sowie Testdaten, mit denen wir das Frontend versorgen können. Jetzt fehlt noch die Möglichkeit, auf diese Daten zuzugreifen. (Zur Erinnerung: Wir haben es mit einer API zu tun, werden also aus dem Frontend HTTP-Request an die API schicken – dazu brauchen wir Routes.).

Füge der Datei web.php unter web-app\routes, folgende Zeile hinzu:

Route::get('groceries/get', 'GroceryController@index');

Rufst du nun zum Test den Link http://localhost/groceries/get auf, solltest du die zuvor in der index-Methode abgerufenen Lebensmittel im JSON-Format angezeigt bekommen.

2.9 Fazit Teil 1: Backend

Der Wesentliche Teil der Backend-Erstellung ist für dieses Tutorial abgeschlossen. Nun benötigen wir nur noch etwas HTML für unser Beispiel, das eine Liste mit Lebensmittel darstellen soll.


3. Erstellen des Frontends

3.1 View anlegen und Bootstrap-Layout hinzufügen

Erstelle unter resources\views die Datei grocerie-list.blade.php und füge etwas HTML-Code hinzu:

<!doctype html>
  <html lang="en">
    <head>
      <!-- Required meta tags -->
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

      <!-- Bootstrap CSS -->
      <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">

      <title>Hello, world!</title>
    </head>
    <body>
      <div class="container mt-4 mb-4">
        <div class="row">
          <div class="col-md">
            <table class="table table-bordered table-striped">
              <thead>
                <tr>
                  <th scope="col">#</th>
                  <th scope="col">Titel</th>
                  <th scope="col">Kategorie</th>
                </tr>
              </thead>
              <tbody>
                <tr>
                  <td scope="row">1</td>
                  <td scope="row">Apfel</td>
                  <td scope="row">Obst</td>
                </tr>
              </tbody>
            </table>
          </div> 
        </div>
      </div>

      <!-- Optional JavaScript -->
      <!-- jQuery first, then Popper.js, then Bootstrap JS -->
      <script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo= " crossorigin="anonymous"></script>
      <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
      <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
      <script type="text/javascript">

     </script>
  </body>
</html>

Dank der ersten Route, die wir im Schritt 2.8 festgelegt haben, können wir die erstellte Seite nun via http://localhost/groceries aufrufen. Du solltest eine Tabelle mit Kopf und einer Spalte sehen, in der „Apple“ steht. Beim Aufruf der Route wird die view()-Methode ausgeführt, die uns einen View zurückgibt (in dem Fall den View grocerie-list.blade.php).

3.2 Controller erweitern

Im nächsten Schritt werden wir die Daten so aufbereiten, dass sie im Frontend angezeigt werden können. Wir befinden uns zwar bereits im Frontend-Teil des Tutorials, aber erst jetzt macht es hinsichtlich der Erklärung Sinn, das Backend entscheidend anzupassen.

Im Schritt 2.7 hatten wir die index()-Methode erstellt, die die erhaltenen Daten im JSON-Format zurückgibt. Jetzt wollen wir aber, dass die Methode HTML zurückgibt. Dazu passen wir den Controller wie folgt an:

public function index() {
  $html = "";

  // Laden aller Spalten, absteigende Sortierung anhand der Spalte 'id'
  $groceries = Grocery::orderBy('id', "desc')→get();

  // Loopen der Ergebnisse
  foreach($groceries as $grocerie)
  {
    // Hänge Daten an Variable an
    $html .= '
      <tr>
        <td scope="row">'. $grocerie->id .'</td>
        <td scope="row">'. $grocerie->title .'</td>
        <td scope="row">'. $grocerie->category .'</td>
      </tr>
    ';
}

// Rückgabe des HTML
  return response()->json($html);
}

Da wir den Tabellenkörper mit unseren Groceries füllen wollen, bedienen wir uns des entsprechenden HTML-Teils. Die Funktionstüchtigkeit kann bereits jetzt getestet werden, da wir im Schritt 2.8 schon die passende Route erstellt haben. Beim Aufruf von http://localhost/groceries/get sollte der Browser nun das zurückgegebene JSON anzeigen.

3.3 Ajax-Request ausführen

Vielleicht ist es dir aufgefallen, dass wir bereits im Schritt 3.1 ein leeres <script>-Tag eingefügt haben. Diesen versehen wir jetzt mit JavaScript-Code:

$(document).ready(function(){

  getGrocerieData();

  function getGrocerieData() {
    $.ajax({
      method: 'GET',
      url: '/groceries/get',
      dataType: 'json',
      success: function(data) {
        console.log(data);
      },
      error: function(error) {
        console.log(error);
      }
    });
  }

});

Das Script im Einzelnen:

  • Sämtlicher Code, der in $(document).ready(function(){ … }) enthalten ist, wird erst ausgeführt, wenn das gesamte Dokument fertig geladen ist.
  • Wir verpacken den Code in der Funktion getGrocerieData(), dass wir ihn zu einem späteren Zeitpunkt eventuell erneut ausführen können. Vorab rufen wir die Methode bereits einmal auf, da wir ja direkt nach dem Laden der Seite die Daten laden wollen.
  • Es folgt der Aufruf der AJAX-Funktionalität ($.ajax({ … })), der wir verschiedene Parameter mitgeben:
    • method: gibt an, welchen Typ von HTTP-Request wir senden.
    • url: der URL unsere API, so, wie er als Route im Schritt 2.8 erstellt wurde.
    • dataType: wir senden die Daten im JSON-Format an die API
    • success: der Inhalt dieses Codeblocks wird ausgegührt, sollte der HTTP-Request erfolgreich gewesen sein. Aus diesem Block heraus werden wir im nächsten Schritt die Daten im HTML anzeigen. Im Moment gibt er die Rückgabe der API in der Browserkonsole aus.
    • error: hier können wir festlegen was passiert, sollte der HTTP-Request fehlgeschlagen haben.

Das Prinzip ist immer gleich. Je nach HTTP-Request definieren wir method, geben den url an und entscheiden dann in success, was wir mit den zurückgelieferten Daten anfangen.

3.4 Daten im HTML-Template anzeigen

Im letzten Schritt fügen wir die erhaltenen Daten in das HTML-Template ein. Da der Controller der API bereits HTML zurückgibt, brauchen wir es nicht mehr mit JavaScript bearbeiten. Die Variable data enthält pures HTML, das wir direkt zu einem Element hinzufügen können.
Das machen wir mit der html()-Methode von JQuery:

$(document).ready(function(){

  getGrocerieData();

  function getGrocerieData() {
    method: 'GET',
    url: '/groceries/get',
    dataType: 'json',
    success: function(data) {
      // console.log(data);
      $('tbody').html(data);
    },
    error: function(error) {
      console.log(error);
    }
  }

});

Fertig! Wenn wir nun die App aufrufen sollten kurze Zeit später die Tabellenspalten auftauchen.

Du kannst den kompletten Code von GitHub herunterladen: https://github.com/nfandrich/dynamic-web-app


0 Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.