TYPO3 Tipps und Tricks: PSR-15 Middleware am Beispiel Mailchimp Webhook

Das Konzept bzw. Design-Pattern "Middlewares" (auch bekannt als "Chain of Responsibility" bzw. "Zuständigkeitskette") - wurde in TYPO3 9 eingeführt. Das Konzept beschreibt wie HTTP-Requests sehr flexibel verarbeitet werden können. Wir werden den Einsatz von "PSR-15 Middelware" am Beispiel "Mailchimp Webhook" zeigen.

Dieses Konzept wird wie von TYPO3 bekannt auch im Core verwendet, um HTTP-Anfragen zu verarbeiten. Damit ein Request verarbeitet wird, durchläuft dieser eine "Chain" (fixen Ablauf) und wird dabei von einer Middleware verarbeitet, eine Middleware kann einen Response erzeugen oder auch einfach zur nächsten Middleware weitergeleitet werden. Über das Backend kann man sich die Liste über "Konfiguration -> HTTP-Middlewaren (PSR-15)" anzeigen.

TYPO3-Middleware im Backend
TYPO3-Middleware im Backend Modul Konfiguration

Da die TYPO3 rest Erweiterung zum Verfassungsdatum des Artikels noch nicht TYPO3 10 kompatibel ist, mussten wir nach einer Alternative suchen um einen POST-Request für den Mailchimp Webhook entgegenzunehmen. Der Kunde verwendet Mailchimp als Newsletter-System und auf der Website des Kunden können Benutzer auch ein Profil erstellen und sich dort vom Newsletter an und abmelden. Meldet sich der Benutzer über den Link in einner Newsletter-Mail ab, soll natürlich auch die Checkbox im Benutzerprofil deaktiviert werdenn. Dazu bietet Mailchimp einen Webhook an. Dabei kann man eine URL angeben und diese wird bei einer Aktualisierung per POST-Request aufgerufen. Die Dokumentation von Mailchimp findet sich hier.

Middleware Konfiguration

Um diesen Webhook entgegenzu nehmen, haben wir eine eigene entwickelt. Um die neue Middleware zu registrieren, muss im Configuration-Ordner der TYPO3-Erweiterung eine Datei mit dem Namen "RequestMiddlewares.php" erstellen.

<?phpreturn [    'frontend' => [        'varioous/rest/mail-chimp-middleware' => [            'target' => Varioous\Rest\MailChimpMiddleware::class,            'before' => [                'typo3/cms-frontend/eid',                'typo3/cms-frontend/tsfe',            ],        ],    ],];

Middleware-Klasse

In der Middleware-Klasse (in der Konfiguration oben registriert) wird der Prozess verarbeitet.

<?phpnamespace Varioous\Rest;use Psr\Http\Message\ResponseInterface;use Psr\Http\Message\ServerRequestInterface;use Psr\Http\Server\MiddlewareInterface;use Psr\Http\Server\RequestHandlerInterface;use TYPO3\CMS\Core\Http\Response;use TYPO3\CMS\Core\Utility\GeneralUtility;use Varioous\Utility\MailchimpUtility;class MailChimpMiddleware implements MiddlewareInterface{    /**     * @param \Psr\Http\Message\ServerRequestInterface $request     * @param \Psr\Http\Server\RequestHandlerInterface $handler     *     * @return \Psr\Http\Message\ResponseInterface     */    public function process(        ServerRequestInterface $request,        RequestHandlerInterface $handler    ): ResponseInterface {        #get called url        $normalizedParams = $request->getAttribute('normalizedParams');        $uri = $normalizedParams->getRequestUri();        #check if url is callled        if (strpos($uri, '/rest/mailchimp-webhook') === 0) {            #check if request is post request and a secret id is submitted (for security reason)            if ($request->getMethod() == 'POST' && isset($_GET['id']) && $_GET['id'] == 'various Interactive ist cool') {                #call method that handles the data that mailchimp sends                MailchimpUtility::mailchimpProfileUpdated(GeneralUtility::_POST());                #after processing data return 200                return (new Response())                    ->withHeader('content-type', 'text/plain; charset=utf-8')                    ->withStatus(200);            } else {                #Mailchimp need that the same URL returns a 200 status on same URL on GET-Request                return (new Response())                    ->withStatus(200);            }        }        #call next middleware        return $handler->handle($request);    }}

Weitere Einsatzmöglichkeiten

  • Slim-Framework: Man könnte so auch ein anderes Framework wie zum Beispiel "Slim" einsetzen und einfach eine komplette REST-Schnittstelle bauen. Hierfür gibt es sogar schon ein Projekt auf github (Allerdings zur Zeit auch noch nicht TYPO3 10 Kompatibel).
  • Middlewares können sowohl für das Frontend als auch Backend eingesetzt werden (siehe oben die Konfiguration).
  • Gewisse Bereiche der Website für bestimmte Benutzer sperren/freischalten.
  • Sprache oder Inhalt der Seite des Benutzers auf Basis einer Abfrage des Standorts anhand der IP durchführen.

Und noch viele weitere Möglichkeiten. Ist man mit diesem Konzept vertraut, ist man in Zukunft viel flexibler in der Umsetzung/Konzeption, da man verschiedene Anwendungsfälle einfach und flexibel umsetzen kann.

Nützliche Links / Quellen

Wir entwickeln digitale Lösungen mit Leidenschaft

Warum wir das tun? Weil die Verwirklichung Ihrer Vision unser größter Anspruch und die schönste Anerkennung ist. Deshalb nehmen wir uns gerne ausreichend Zeit für die Realisierung Ihres digitalen Projekts.

Kontaktieren Sie uns, wir sind gerne für Ihre Fragen da:

Passend zu diesem Thema:

TYPO3 Tipps und Tricks: Cache für einzelne Extbase-Objekte leeren

TYPO3 Tipps und Tricks: Cache für einzelne Extbase-Objekte leeren

Kürzlich bin ich bei einem Projekt vor folgendem Problem gestanden: Per Plugin werden Extbase-Objekte auf einer Seite ausgegeben und diese auch gecach…

Ajax mit TYPO3 – so funktionierts!

Ajax mit TYPO3 – so funktionierts!

Es gibt diverse Ansätze, um Ajax im Typo3 Frontend zu nutzen. Wir haben hier einen für uns doch sehr einfachen und praktikablen Weg, den wir euch nich…

TYPO3 Tipps und Tricks: Manueller/Programmatischer Login in Controller-Action (TYPO3 9)

TYPO3 Tipps und Tricks: Manueller/Programmatischer Login in Controller-Action (T…

Manchmal gibt es bei Web-Projekten die Notwendigkeit einen Login programmatisch (manuell, im PHP-Code) durchzuführen. Ein Kunde hat vor kurzem folgend…