REST-API mit eigenem "Namespace" verwenden

Hallo! Bei uns ist Shopware 4.3.x in Betrieb und ich hatte mich gefragt ob es möglich sei, einen eigenen “Namespace” mit der vorhandenen REST-API zu verwenden. D.h. ist es zB möglich solche Entry-Points zu generieren: Normale API: example.com/api/articles example.com/api/articles/2 Beispiel A: example.com/api/moep/articles example.com/api/moep/articles/2 oder Beispiel B: example.com/moep-api/articles example.com/moep-api/articles/2 Was ich bisher versucht hatte war, einen Frontend Controller zu erstellen, der von Shopware_Controllers_Api_Rest erbt; dadurch erhalte ich schonmal die “Korrekte View” als Rückgabewert, jedoch ist dann mein Controller (Beispiel B) moep-api und nicht, wie erwartet articles (was klar ist, wenn ich ihn als “MoepApi” controller anlege) - und dementsprechend ist “2” nur ein get-key ohne value. Hier wäre meine Frage, zB. ob es möglich ist zu sagen, daß bei der articlesAction im MoepApi Controller an einen anderen (auch Shopware_Controllers_Api_Rest) weitergeleitet wird, anstatt direkt einen Rückgabewert zu generieren, sodaß ich am Ende doch einen voll funktionsfähigen Controller auf articles habe. Bei Beispiel A bin ich komplett gescheitert, da das ja am /api/ Shopware_Controllers_Api_Rest hängt. Dort wird ja manuell der prefix /api/ im preDispatch gesetzt. public function preDispatch() { $this-\>Front()-\>Plugins()-\>ViewRenderer()-\>setNoRender(); // todo@bc set url in shopware specific way $serverUrlHelper = new Zend\_View\_Helper\_ServerUrl(); $this-\>apiBaseUrl = $serverUrlHelper-\>serverUrl() . $this-\>Request()-\>getBaseUrl() . '/api/'; } Ich hatte (in Beispiel A) versucht das nachzubauen indem ich einen eigenen Resourcen-Controller hatte, der dann in seinem preDispatch die base url überschreibt, jedoch wurde das komplett vom System ignoriert, und ich hab beim aufruf meiner moep-api eine Weiterleitung zur Default Index-Seite bekommen. Wäre super wenn jemand eine Idee hätte, wo man evtl. ansetzen müsste um die API um entweder Beispiel A oder Beispiel B zu erweitern, wobei man dann immernoch auf den eigentlichen REST Entry-Points echte Shopware REST Controller hat, die die integrierte Core-CRUD Verarbeitung bereitstellen. Schöne Grüße, Marc Edit: Danke Daniel für deine schnelle Hilfe, das ist insofern gelöst, daß ich weiß was zu tun ist

Hi, das nicht ohne Weiteres möglich. Das Routing findet hier statt: \ShopwarePlugins\RestApi\Components\Router::assembleRoute. Deine “moep-api” ist aus SW-Sicht ein Module, für das du dein eigenes Routing implementieren müsstest, wenn du das API-Verhalten nachstellen möchtest (vgl. \Shopware_Plugins_Core_RestApi_Bootstrap::onDispatchLoopStartup). Davon würde ich abraten, weil die Module von einigen Modulen explizit geblacklistet sind (if($module == ‘api’) return). Die Möglichkeiten, die das aktuelle Routing bietet, sind a) Versionen (/api/v2/articles/2) und b) Sub-Ressourcen (/api/articles/2/images/4). Beides wird zur Zeit noch nicht im Standard genutzt, könnte es dir aber bspw. ermöglichen, bestimmte Endpunkte unter einer Ressource zusammen zu fassen: (/api/moep/1/my-products/12). Letztlich ist da also viel möglich - ich würde aber an deiner Stelle doch möglichst nah am Standard bleiben und auf den “eigenen API-Namespace” verzichten. Daniel

Hi Daniel, danke für die schnelle Antwort! :slight_smile: [quote=“Daniel Nögel”][…]Die Möglichkeiten, die das aktuelle Routing bietet, sind a) Versionen (/api/v2/articles/2) und b) Sub-Ressourcen (/api/articles/2/images/4). Beides wird zur Zeit noch nicht im Standard genutzt, könnte es dir aber bspw. ermöglichen, bestimmte Endpunkte unter einer Ressource zusammen zu fassen: (/api/moep/1/my-products/12).[/quote] Das sieht eig. nach genau dem aus, was ich vor hatte (also eine eigene “moep-api” version, oder “moep-api/1” Haupt-Resource mit SubResourcen zu erstellen). Gibt es irgendwo Doku zu SubResourcen bzw. Versionen? (bzw. an welchen Stellen ungefähr im Code sollte ich da nachsehen) [quote=“Daniel Nögel”][…]Letztlich ist da also viel möglich - ich würde aber an deiner Stelle doch möglichst nah am Standard bleiben und auf den “eigenen API-Namespace” verzichten.[/quote] Hmm zu dem Entschluss bin ich momentan auch gekommen, ich werde meine Ressourcen erstmal MoepArticles / MoepCustomers etc. nennen und dann über /api/moep-articles/ aufrufen. Nochmal kurz eine Frage, ich war mir nicht sicher ob ich da nicht einen neuen Thread aufmachen sollte, aber will ja auch nicht direkt nach der Anmeldung rumspammen :smiley: Die API ist momentan wie sie implementiert ist nicht als… ich nenne es mal “Frontend API” gedacht, sehe ich das richtig? Also so wie ich das gesehen habe ist es derzeit nicht möglich sich zB als Customer “Marc” anzumelden und dann nur auf die Customer-Daten von “Marc” zugreifen zu dürfen; ich kann nur global mit dem API-User sagen “du darfst jetzt alle Customer sehen” – hab ich das richtig erfasst? Ist so eine “Frontend API” geplant? (Weil ich nämlich an jener gerade sitze, und ich weiß nicht genau was ihr vor habt). Außerdem: Customer Authentication ist momentan nur über Session ID in Cookies gelöst, richtig? Es gibt (soweit ich gesehen habe) momentan keine Möglichkeit ein Token-Basiertes System zu verwenden, das bereits in Shopware / Zend integriert ist, ja? Schöne Grüße, Marc

Hi Marc, die Versionierung ist zZt noch nicht dokumentiert, weil wir das eher als Option für die Zukunft gedacht haben. Du kannst dir das am besten hier ansehen: \ShopwarePlugins\RestApi\Components\Router::assembleRoute Dann rufst du einfach mal eine Url auf wie http://localhost/sw4/api/articles/3/test/3 Im Log siehst du dann eine Fehlermeldung wie [2015-01-12 15:41:48] core.ERROR: exception 'Enlight\_Controller\_Exception' with message 'Action "Api\_Articles\_getTestAction" not found failure' in /srv/http/sw4/engine/Library/Enlight/Controller/Action.php:389 Daran siehst du, dass du eine Methode getTestAction im Controller implementieren musst. In der hast du dann die ID der Hauptressource zur Verfügung (getParam(‘id’)) sowie die der subResource (getParam(‘subId’)). Falls du die Versionierung nutzt, hast du einfach einen Param “version”, der im Standard immer “1” ist. Zu den anderen Fragen: Ja, die API ist eher administrativ und nicht als Frontend-API konzipiert. Ein Token-basiertes Session-Management fürs Frontend ist meines Wissens nicht möglich. Schöne Grüße, Daniel

1 Like