TYPO3 RequestFactory – saubere API-Integration am Beispiel SharePoint

In modernen TYPO3-Projekten besteht häufig die Anforderung, Daten aus externen Systemen einzubinden – beispielsweise CRM-Lösungen, Zahlungsanbieter oder Microsoft SharePoint.

TYPO3 stellt dafür die offizielle Klasse TYPO3\CMS\Core\Http\RequestFactory bereit. Sie bietet eine elegante und PSR-7-konforme Möglichkeit, HTTP-Anfragen (GET, POST usw.) zu versenden.

Warum RequestFactory?

  • klare API mit schlanken Methoden
  • PSR-7-konforme Request- und Response-Objekte
  • basiert intern auf Guzzle, ohne direkten Guzzle-Zugriff
  • nahtlose Integration in TYPO3 Dependency Injection

PSR-7 und Guzzle

  • PSR-7 definiert Standard-Interfaces für HTTP-Requests, -Responses, Header, Streams usw.
  • Guzzle ist ein weit verbreiteter HTTP-Client in PHP, den TYPO3 intern nutzt. Mit RequestFactory profitiert man von Guzzle, bleibt aber in der TYPO3-Architektur.

Einfaches Beispiel: GET
 

Warum GET?

  • Lesender Zugriff: GET ist die richtige Wahl, wenn nur Daten abgerufen werden sollen – ohne den Zustand auf dem Server zu verändern.
  • Klarheit & Caching: GET-Requests sind transparent und können leicht gecacht werden (z. B. von TYPO3-Caching oder Proxy-Systemen).
  • Typische Use Cases:
    • Inhalte aus einem Headless-CMS oder SharePoint abrufen
    • Produkt- oder Benutzerlisten laden
    • einfache Health-Checks von externen Diensten

GET eignet sich also immer dann, wenn man bestehende Informationen abfragen möchte, ohne etwas zu „schreiben“ oder zu verändern.

                            use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Http\RequestFactory;

$requestFactory = GeneralUtility::makeInstance(RequestFactory::class);

$response = $requestFactory->request(
   'https://api.example.com/data',
   'GET',
   [
       'headers' => ['Accept' => 'application/json']
   ]
);

if ($response->getStatusCode() === 200) {
   $data = json_decode($response->getBody()->getContents(), true);
}

                        

Integration mit SharePoint API (mit Logging)

Beim Zugriff auf das Microsoft Graph API für SharePoint ist typischerweise ein OAuth-Token nötig.
Wir erweitern das Beispiel um Fehlerbehandlung und Logging via TYPO3 Logger.

                            declare(strict_types=1);

namespace Vendor\Extension\Api;

use TYPO3\CMS\Core\Http\RequestFactory;
use TYPO3\CMS\Core\Log\LogManager;
use TYPO3\CMS\Core\Log\Logger;
use TYPO3\CMS\Core\Utility\GeneralUtility;

final class SharePointClient
{
    private Logger $logger;

    public function __construct(
        private readonly RequestFactory $requestFactory
    ) {
        $this->logger = GeneralUtility::makeInstance(LogManager::class)
            ->getLogger(__CLASS__);
    }

    public function getDocuments(string $siteId, string $token): array
    {
        $url = sprintf(
            'https://graph.microsoft.com/v1.0/sites/%s/drive/root/children',
            $siteId
        );

        try {
            $response = $this->requestFactory->request($url, 'GET', [
                'headers' => [
                    'Authorization' => 'Bearer ' . $token,
                    'Accept' => 'application/json'
                ],
                'timeout' => 15.0
            ]);

            if ($response->getStatusCode() !== 200) {
                $this->logger->error('SharePoint API-Fehler', [
                    'status' => $response->getStatusCode(),
                    'body'   => $response->getBody()->getContents(),
                ]);
                return [];
            }

            return json_decode($response->getBody()->getContents(), true) ?? [];

        } catch (\Throwable $e) {
            $this->logger->critical('SharePoint Request fehlgeschlagen', [
                'message' => $e->getMessage(),
                'code'    => $e->getCode(),
            ]);
            return [];
        }
    }
}

                        

Best Practices

  1. Dependency Injection
    RequestFactory immer per Konstruktor injizieren, nicht per GeneralUtility::makeInstance() im Code.
  2. Logging nutzen
    • error für erwartete API-Probleme (z. B. 401 Unauthorized)
    • critical für unerwartete Exceptions
  3. Timeout setzen
    Externe Requests sollten nie unendlich blockieren.
  4. Content-Type prüfen
    Nicht alle APIs liefern konsistente Header. Vor json_decode() sicherstellen, daß der Inhalt wirklich JSON ist.
  5. Caching
    Wenn Daten nicht in Echtzeit gebraucht werden, ist TYPO3 Cache sinnvoll.

Fazit

RequestFactory ist das Herzstück jeder robusten API-Integration in TYPO3.
Besonders bei Systemen wie SharePoint ist neben dem Request-Handling auch sauberes Fehler-Logging unverzichtbar, um Probleme schnell zu erkennen und Support-Aufwand zu minimieren.

Mit klarer Architektur, PSR-7-Standard und der TYPO3-Logger-Integration lassen sich Integrationen entwickeln, die verlässlich, nachvollziehbar und erweiterbar sind.

PHP TYPO3