response()->acmeFailure(...) hinzufügen, ohne dass Controller von einer Basisklasse erben müssen.
Diese Seite basiert auf der offiziellen Laravel-Dokumentation im Standard-Branch 13.x und der offiziellen Implementierung des neuesten Framework-Releases v13.40.0, geprüft am 8. November 2026. Aufbauend auf den Grundlagen von Responses und dem Macroable-Trait behandelt sie die Grenzen, die Sie beachten sollten, wenn Sie ein Macro als öffentliche API eines verteilten Pakets pflegen.
Registrierung an der Factory, nicht an der Response
Der NameResponse bezeichnet sowohl eine Facade, die die Erzeugung einer Antwort anfordert, als auch die Klasse der erzeugten HTTP-Antwort. Response::macro() aus der offiziellen Dokumentation erweitert ResponseFactory, also die Klasse, in die die Facade aufgelöst wird.
response() ohne Argumente gibt die Factory zurück. response('Inhalt') und response(null) geben dagegen eine mit make() erzeugte Antwort zurück und rufen daher nicht dasselbe Ziel auf.
Eine Erzeugungs-API für Fehler-JSON veröffentlichen
Im Service Provider registrieren
Registrieren Sie in der Methodeboot() von src/HttpServiceProvider.php ein Macro mit Paketpräfix. Wie der Provider geladen wird, erfahren Sie unter Paket-Discovery.
Der öffentliche Vertrag in diesem Beispiel besteht aus JSON mit error.code und error.message sowie einem HTTP-Status zwischen 400 und 599. Diese Statusbeschränkung ist keine Einschränkung des Macro-Mechanismus von Laravel. Das Paket legt sie für eine reine Fehler-API fest.
runningInConsole()-Bedingung. Auch HTTP-Feature-Tests laufen über die CLI.
Ein Provider, der nur diese Registrierung übernimmt, muss auch kein verzögerter Provider sein, der auf die Auflösung eines Dienstes wartet. Wie verzögerte Registrierung funktioniert, erfahren Sie unter Verzögerte Service Provider.
Aus einem Controller aufrufen
Nachdem Ihre Geschäftslogik einen Konflikt erkannt hat, übergeben Sie den festgelegten Fehlercode und eine Meldung für den Benutzer.409, und das JSON sieht wie folgt aus. Wie beim normalen json() ist der Content-Type application/json.
Das Macro erzeugt nur die Antworten, bei denen Sie es aufrufen. Es wandelt Validierungsausnahmen oder Authentifizierungsfehler nicht automatisch in dieses Format um. Es fügt auch keine Umschaltung zwischen HTML und JSON abhängig vom
Accept-Header hinzu.$this in der Closure und der Aufrufpfad
Die Factory verwendet Macroable. Wenn Sie eine nicht definierte Methode einer Instanz aufrufen, sucht __call() das registrierte Macro und bindet eine normale Closure neu an die aufrufende Instanz.
Auch wenn der Registrierungscode in einer Methode des Service Providers steht, ist $this zur Laufzeit die Factory und nicht der Service Provider. Deshalb ruft $this->json() im Beispiel die normale Methode der Factory auf.
- Definieren Sie Macros, die
$thisverwenden, mit einer normalenfunction (...) { ... }. Einestatic functionhat kein Instanz-$this. - Wenn Sie ein invokable Objekt registrieren, wird es nicht wie eine Closure neu gebunden. Benötigte Abhängigkeiten erhält dieses Objekt selbst, zum Beispiel über seinen Konstruktor.
- Die Argumente des Macros sind die Argumente, die der Aufrufer übergibt. Auch wenn Sie
Requestoder Ähnliches als Typ angeben, injiziert Macroable es nicht automatisch aus dem Container.
Response::acmeFailure() sieht statisch aus, wird intern aber an die Factory-Instanz weitergeleitet. Illuminate\Routing\ResponseFactory::acmeFailure() auf der konkreten Klasse ist dagegen ein echter statischer Aufruf, und __callStatic() bindet die Closure ohne Instanz. Ein Macro wie dieses, das $this->json() verwendet, unterstützt keine statischen Aufrufe auf der konkreten Klasse.
Namenskollisionen als Kompatibilitätsproblem behandeln
macro() weist lediglich einem statischen Array mit dem Namen als Schlüssel einen Wert zu. Die Registrierung eines vorhandenen Namens erzeugt keine Warnung.
Wählen Sie statt eines allgemeinen Namens wie
failure einen Namen, der Ihr Paket erkennen lässt, etwa acmeFailure. Prüfen Sie bei Laravel-Updates zusätzlich mit method_exists(ResponseFactory::class, 'acmeFailure') auf Kollisionen mit echten Methoden.
Wenn Sie hasMacro() prüfen und die Registrierung bedingungslos überspringen, verwenden Sie womöglich die Implementierung eines anderen Pakets, als wäre sie Ihre eigene API. Nur wenn Sie „die Anwendung kann es durch vorherige Registrierung überschreiben“ zur Spezifikation machen, sollten Sie diese Rangfolge zusammen mit den erforderlichen Argumenten und dem Rückgabewert veröffentlichen. Das obige Beispiel folgt dem Grundsatz, bei jedem Start des Providers die eigene Definition des Pakets zu registrieren.
Registrierungszustand und Lebensdauer der Antwort trennen
Das Macro-Register ist eine statische Eigenschaft der Factory. Das Neuerzeugen der Factory oder das Löschen der aufgelösten Facade-Instanz leert dieses Register nicht. Auch in Tests, die die Anwendung innerhalb desselben PHP-Prozesses neu erzeugen, kann der Registrierungszustand bestehen bleiben. Das Beispiel-Macro lässt dagegen bei jedem Aufrufjson() eine neue JsonResponse erzeugen. Geteilt wird die Erzeugungslogik, nicht der Inhalt oder die Header der Antwort selbst.
Diese Grenzen sollten Sie in langlebigen Workern einhalten.
- Erfassen Sie bei der Registrierung nicht den aktuellen Request, den authentifizierten Benutzer oder den Mandanten mit
use (...). Übergeben Sie diese Werte beim Aufruf als Argumente. - Verwenden Sie keine bei der Registrierung erzeugte Antwort wieder. Geben Sie jedes Mal eine neue Antwort zurück.
- Wenn Sie Konfiguration bei der Registrierung als Wert erfassen, nehmen Sie in die Spezifikation auf, dass dieser Wert im Prozess erhalten bleibt.
- Starten Sie nach einem Paket-Update langlebige Prozesse neu, damit der neue Registrierungscode wirksam wird.
Den HTTP-Vertrag mit echten Rückgabewerten testen
Legen Sie in einer Laravel-13-Testanwendung, die das Paket über Composer laden kann, die folgende Dateitests/Feature/ResponseMacroTest.php an. Zu Tests\TestCase und den Grundlagen von HTTP-Tests siehe HTTP-Tests, zur Einrichtung einer eigenständigen Paketumgebung siehe Pakete testen.
Response::shouldReceive('acmeFailure'), werden Macro-Registrierung, Closure-Bindung und JSON-Erzeugung nicht ausgeführt. Halten Sie Prüfungen der Aufrufanzahl getrennt und prüfen Sie wie oben die echte HTTP-Antwort.
Behandeln Sie außerdem Inhalt, Status und Header, die Nutzer erhalten, als Teil der Kompatibilität.
- Halten Sie
error.codefür die maschinelle Auswertung stabil und unterscheiden Sie es von Änderungen der Anzeigemeldung. - Argumentnamen werden als benannte Argumente verwendet. Prüfen Sie die Auswirkungen ihrer Änderung daher genauso wie bei Standardwerten oder Reihenfolge.
- Geben Sie Antworten ohne Inhalt wie
204nicht als Fehler-JSON zurück, sondern über eine andere API wienoContent(). - Wenn Sie Erweiterungen zulassen, die den
Content-Typeüber eigene Header ändern, halten Sie ihn mit dem Inhaltsformat konsistent. - Wenn es um Datenserialisierung oder Paginierung geht, implementieren Sie diese nicht allein mit Macros neu, sondern ziehen Sie auch Eloquent-API-Ressourcen in Betracht.
Checkliste für die langfristige Pflege
- In den unterstützten Laravel-13-Kombinationen startet der Provider, und das Macro ist sowohl über den Helper als auch über die Facade aufrufbar.
- Der Macro-Name kollidiert weder mit anderen Registrierungen noch mit echten Methoden der Factory.
- Die Kompatibilität von JSON-Schlüsseln, HTTP-Status, Headern, Standardwerten und benannten Argumenten ist getestet.
- Aufeinanderfolgende Aufrufe teilen keine Antworten, und bei der Registrierung werden keine Request- oder Benutzerinformationen gespeichert.
- Tests, die Registrierungen zurücksetzen, sind von anderen Paketen isoliert.
- Der Neustart langlebiger Prozesse ist Teil des Update-Verfahrens.
Verwendete Primärquellen
- Offizielle Laravel-Dokumentation: Response macros und JSON responses (13.x)
- Offizielle Laravel-Dokumentation: Package development (13.x)
- Die Response-Facade und ihr Auflösungsziel (v13.40.0)
- Weiterleitung der Facade an die Instanz (v13.40.0)
- Der Helper response() (v13.40.0)
- Erzeugungslogik der ResponseFactory (v13.40.0)
- Registrierung, Bindung und Zurücksetzen in Macroable (v13.40.0)
- Offizielle Tests für Macroable (v13.40.0)