Expert Topics

Wie erstellt man eine einfache REST API in Symfony?

9 Kommentare // Lesezeit: 17 min.

Hinweis: Dieser Artikel ist Teil einer Serie. Der erste Artikel befasste sich mit der Erstellung eines ersten Symfony 2-Projekts, der zweite mit Symfony 2 Formularen.

In diesem Artikel beschreibe ich eine schöne und einfache Möglichkeit, eine REST-API mit dem Symfony-Framework zu implementieren.

Was ist eine REST-API?

REST API ist ein Webdienst, der die REST-Architektur verwendet.

REST = "REpresentational State Transfer"
API = "Application Programming Interface"

Die REST-Architektur ist ressourcenbasiert, d. h. sie konzentriert sich auf Ressourcen und nicht auf Aktionen, d. h. sie ruft (in der URI) eine Ressource auf (in diesem Lernprogramm ist die Ressource "type") und verwendet ein http-Verb (method), um anzugeben, welche Operation sie mit der Ressource durchführen möchte.

REST läuft in der Regel über http und hat mehrere architektonische Beschränkungen:

  1. Entkopplung der Verbraucher von den Produzenten
  2. Stateless
  3. Nutzt einen Cache
  4. Nutzt ein mehrstufiges System
  5. Nutzt eine einheitliche Schnittstelle

1. Abhängigkeiten installieren

Eine gute Praxis in der Welt der Programmierung ist es, nicht bei jedem Projekt das Rad neu zu erfinden. - Verwenden Sie den Code wieder. Wenn es einen guten Code (Paket) gibt, der unsere Bedürfnisse erfüllt, sollten wir ihn verwenden. In diesem Projekt habe ich ein cooles Paket verwendet: FOSRest bundle (und 2 weitere), um mir bei der Erstellung einer REST-API zu helfen.

Binden wir also die Bundles über den Composer ein. Fügen Sie diese Zeilen zu "require" Abschnitt Ihrer composer.json Datei:

Oder Sie können diese Bundles über den Composer-Befehl require hinzufügen.

Wichtiger Hinweis:

Vielleicht haben Sie bemerkt, dass ich '@dev'-Versionen verwendet habe. Verwenden Sie Dev-Versionen nur, wenn Sie keine andere Wahl haben, oder wenn Sie einen guten Grund dafür haben. Sie sollten stattdessen die neueste stabile Version verwenden.

Vergessen Sie nicht, die Bundles zur AppKernel-Klasse hinzuzufügen:

2. Datenbank erstellen

Sie müssen die Datenbankparameter in app/config/parameters.yaml festlegen, oder Sie können den Befehl composer install ausführen, um die Datei automatisch zu generieren. In jedem Fall müssen Sie die notwendigen Datenbankparameter angeben.

Führen Sie dann diesen Befehl aus:

php app/console doctrine:database:create
 


Braucht Ihr Unternehmen einen Webspezialisten, mit dem es auf Augenhöhe sprechen kann?

 


3. Erstellen wir unsere Entität

In diesem Artikel werde ich die Entität Type vorstellen und eine REST-API für sie erstellen. Sie ist mit anderen Entitäten verknüpft, aber sie werden hier nicht angezeigt, da der gesamte Prozess der Erstellung einer API für die Entität Type auf jede andere Entität angewendet werden kann.

Typ-Entitätsklassen können mit diesem interaktiven Befehl erstellt werden:

php app/console doctrine:generate:entities TypoScriptBackendBundle:Type

Oder Sie können die php-Datei im Entity-Verzeichnis erstellen.

Führen Sie diesen Befehl aus, um das generierte SQL zu sehen:

php app/console doctrine:schema:update --dump-sql

Wenn Sie mit dem erzeugten SQL zufrieden sind, führen Sie diesen Befehl aus, um die Tabelle in der Datenbank zu erzeugen:

php app/console doctrine:schema:update --force

Wir benötigen auch die Klasse TypeRepository. Sie wird automatisch erstellt, wenn Sie den Befehl ausführen:

php app/console doctrine:generate:entities TypoScriptBackendBundle:Type

Wenn es nicht erstellt wird, machen Sie es händisch.

4. Die Routes und die Konfiguration des FOSRest-Bundles

Erstellen Sie die Datei routes.yaml in Ihrem Bundle und fügen Sie sie in die Haupt-Routing-Datei ein:

5. Symfony-Formular

Wir brauchen eine Möglichkeit, die von der API übermittelten Daten zu validieren. Der einfachste Weg dazu ist die Verwendung von Symfony-Formularen. Lassen Sie uns also ein einfaches Symfony-Formular für die Entität Type erstellen:

6. REST-Controller

Wir kommen zum wichtigsten Teil - der Implementierung der REST-Methoden.

Um die Leistungsfähigkeit des FOSRest-Bundles zu nutzen, sollte unser TypeController die Klasse FOS\RestBundle\Controller\FOSRestController erweitern:

Fügen wir dem Controller REST-Methoden hinzu.

6.1 GET-Verfahren

getTypeAction erzeugt eine HTTP-GET-Methode für die type Ressource. Es kann von der Konsole (Linux) mit dem Befehl curl getestet werden:

curl -G 127.0.0.1/app.php/api/typoscript/types/1

Standardmäßig wird der Typ im JSON-Format zurückgegeben, aber auch XML wird unterstützt, und das Format kann explizit angegeben werden:

curl -G 127.0.0.1/app.php/api/typoscript/types/1.xml

Was macht diese Methode also? Sie holt die Entität nach ID aus dem Repository (Datenbank). Wenn die Entität nicht gefunden wird, wird die NotFoundHttpException ausgelöst. (Wir werden später in diesem Text über Ausnahmen sprechen.) Wenn die Entität gefunden wird, wird sie zurückgegeben, und das FOSRest-Bündel konvertiert sie automatisch in das gewünschte Format.

6.2 POST-Verfahren

Wir verwenden die postTypeAction, um einen neuen Typ zu erstellen und ihn in der Datenbank zu speichern. Das geschieht in der Methode createNewType:

Wie Sie sehen können, verwenden wir in der Methode processForm ein zuvor erstelltes Symfony-Formular, um die Anfragedaten zu validieren. Wenn die Daten gültig sind, werden sie in der Datenbank gespeichert.

6.3 PUT-Verfahren

Wenn die HTTP PUT-Methode aufgerufen wird, sollten wir die Datenbank nach der Entität mit der angegebenen ID durchsuchen.

Wenn wir die Entität finden, wenden wir die Anfragedaten auf sie an, validieren sie und halten sie fest, wenn sie gültig sind. Wenn die Daten ungültig sind, wird eine Ausnahme ausgelöst. All dies, mit Ausnahme der Suche, wird in der processForm-Methode durchgeführt, die im obigen Text vorgestellt wird.

Wenn die Entität nicht in der Datenbank vorhanden ist, wird sie erstellt, validiert und persistiert, genau wie die POST-Methode aufgerufen wird.

6.4 DELETE-Verfahren

Diese Methode löscht einen Typ nach ID. Zunächst wird versucht, den Typ aus der Datenbank zu holen. Wenn wir ihn finden, löschen wir ihn, andernfalls wird eine Ausnahme geworfen.

6.5 PATCH-Verfahren

Wie Sie sehen können, erhalten wir zuerst die Entität und "patchen" sie dann - aktualisieren einige ihrer Felder. Hier liegt der Hauptunterschied zwischen den HTTP-Methoden PUT und PATCH - PATCH aktualisiert nur die Felder, die in den Anfragedaten übermittelt wurden, und andere Felder bleiben unverändert. Während PUT alle Felder der Entität aktualisiert. Wenn einige Felder in den Anfragedaten ausgelassen werden, werden diese Felder in der Entität auf NULL gesetzt. Außerdem kann die PUT-Methode eine neue Entität erstellen, während dies bei PATCH nicht möglich ist.

7. Ausnahmen

Ein guter Umgang mit Ausnahmen ist wichtig, denn sie helfen Ihnen bei der Entwicklung, indem sie Ihnen wertvolles Feedback geben, und sie zeigen dem Benutzer einen Fehler an, wenn er auftritt.  Das FOSRest-Bundle fängt die von den Controller-Aktionen ausgelösten Ausnahmen ab und erstellt http-Fehlermeldungen, die an den Benutzer zurückgegeben werden.

Wichtig!

Das Verhalten von FOSRest-Bundles in Entwicklungs- und Produktionsumgebungen ist unterschiedlich. In der Entwicklungsumgebung werden die vollständigen Fehlermeldungen aller nicht abgefangenen Ausnahmen an den Benutzer (Entwickler) gesendet, während in der Produktionsumgebung nur die http-Fehlercodes mit der entsprechenden Meldung an den Benutzer gesendet werden. Wenn zum Beispiel ein Datenbankfehler durch ungültige Benutzerdaten verursacht wird, gibt das FOSRest-Bundle den http-Code 500 mit der Fehlermeldung zurück: 'Interner Serverfehler', was gut ist. Auf diese Weise werden sensible interne Informationen über das System (die z.B. in einer Datenbankfehlermeldung enthalten sein könnten) geschützt. Wenn der Entwickler den Benutzern jedoch eine aussagekräftigere Meldung geben möchte, muss er eine Ausnahmeklasse registrieren und sie mit einem http-Fehlercode verknüpfen. Dann kann er eine benutzerdefinierte Fehlermeldung mit mehr Details über den Fehler einstellen und hat dennoch die Kontrolle über die Systemdaten, die dem Benutzer präsentiert werden.

Hier ist ein Beispiel für eine benutzerdefinierte Ausnahmeklasse:

Alle benutzerdefinierten Ausnahmen müssen in der Datei config.yaml registriert werden, was Sie im Abschnitt über Routes und Konfiguration in diesem Artikel sehen können.

Alle vom System ausgelösten Ausnahmen (z. B. doctrine) müssen abgefangen werden, und die nützlichen Informationen müssen extrahiert und dem Client in einer geeigneten Nachricht präsentiert werden. Das ist die Aufgabe der Funktion throwFosrestSupportedException, die von catch-Blöcken meines Codes aufgerufen wird. In diesem Beispiel tut die Funktion nichts Sinnvolles, sie überträgt lediglich die Fehlermeldung an die BadRequestDataException, die in der FOSRest-Bundle-Konfiguration registriert ist und einen http-Fehlercode zugewiesen hat. Dieser Funktion fehlt also der Code, der die Ausnahme analysieren und die Meldung für den Client anpassen sollte.

In unserem Git-Repository können Sie den kompletten Code sehen, der in diesem Tutorial verwendet wird. Prost! :)

Kontaktieren Sie uns!

Wir sind eine Digitalagentur, die sich auf die Entwicklung digitaler Produkte spezialisiert hat. Unsere Kernthemen sind Webseiten und Portale mit TYPO3, eCommerce mit Shopware und Android und iOS-Apps. Daneben beschäftigen wir uns mit vielen weiteren Themen im Bereich Webentwicklung. Kontaktieren Sie uns gerne mit Ihren Anliegen!

Kommentare

  • Stefan Galinski

    Stefan Galinski

    am 26.10.2015

    Thanks Damjan for this extensive tutorial! Thanks Damjan for this extensive tutorial!

  • Maximilian Mayer

    Maximilian Mayer

    am 26.10.2015

    Nice Symfony tutorials, Damjan! :-) Nice Symfony tutorials, Damjan! :-)

  • olivedev

    olivedev

    am 05.10.2016

    This is quite a long and tiring process. It would take a really long time for you to create a simple rest api. You can make it much quicker like shown in this guide on how to create rest api in [...] This is quite a long and tiring process. It would take a really long time for you to create a simple rest api. You can make it much quicker like shown in this guide on how to create rest api in Symfony 3.1: https://www.cloudways.com/blog/rest-api-in-symfony-3-1/

  • pHzao

    pHzao

    am 04.11.2017

    The best tutorials i have read until now! Good Work! The best tutorials i have read until now! Good Work!

  • PARDEEP

    PARDEEP

    am 09.03.2018

    Nice Article ! i am also working restful api with symfony and publish article on that
    Iink: https://www.cloudways.com/blog/rest-api-in-symfony-3-1/ Nice Article ! i am also working restful api with symfony and publish article on that
    Iink: https://www.cloudways.com/blog/rest-api-in-symfony-3-1/

  • Lukasz

    Lukasz

    am 24.11.2018

    Something less simple - hope documentation is ok :) https://github.com/tulik/symfony-4-rest-api Something less simple - hope documentation is ok :) https://github.com/tulik/symfony-4-rest-api

  • Stas

    Stas

    am 03.09.2019

    Just a short note. API - application programming interface Just a short note. API - application programming interface

  • johan

    johan

    am 27.06.2020

    Just to mention that API means "Application Programming Interface" and NOT "APplication Interface" Just to mention that API means "Application Programming Interface" and NOT "APplication Interface"

    • Stefan Galinski

      Stefan Galinski

      am 27.06.2020

      Thanks. I changed that. Thanks. I changed that.