2024. április 25., csütörtök

Gyorskeresés

PHP Web service 3: Extensibility

Írta: | Kulcsszavak: php . soap . web service . service . extensibility

[ ÚJ BEJEGYZÉS ]

Hol is tartunk? Service van, valamilyen szinten védve is (idő közben a WSDL is), de ezen túl is van még lehetőség a szolgáltatásunk fejlesztésében, mert üzenetek sima kiszolgálásán túl nem sok mindenre alkalmas, illetve akadhatnak olyan feladatok, amelyek megoldása felesleges zavart kelthetnek a service osztályunk kódjában.

A kulcsa a bővíthetőségnek szintén az, hogy service implementálásakor ne kelljen sokat azzal foglalkoznunk, mi hogyan működik, illetve ne keltsünk a feleslegesnél nagyobb zavart a rendszerben.

Mi az egyáltalán, amivel foglalkoznunk kellene?
- valamilyen extra header-t kell kezelnünk a szerveren
- paraméterek vizsgálata a service adott operation-jének meghívása előtt
- operation meghívása
- visszatérési érték vizsgálata serialization előtt
- valamiféle hibakezelés
- más?

Mivel rendelkezünk eddig?
- valahogyan értelmeződék a kérés (MVC routing - handler mechanizmus)
- autentikálunk, ha kell
- kiszolgáljuk a WSDL kéréseket
- kiszolgáljuk a SOAP kéréseket, futtatunk egy SoapServer-t

Szerintem érződik, hogy ez az infrastruktúra nem elég a fentiek megoldására, hiszen pl. a SoapServer objektumon dolgozik teljesen zárt rendszerben, nem férhetünk hozzá.

Megoldásként egyetlen lehetőségünk, ha a SoapServer-nek egy proxy object-et adunk (nálam ServiceDispatcher-nek hívják), amin keresztül hívódnak meg a service-ünk metódusai. Szerencsénk van, mert a PHP rendelkezik egy varázslatos képességgel: __call magic method. Ezt nagyvonalakban arra használhatjuk, hogy előre a class által nem definiált metódusokat (vagy egyéb funkcionalitást) hívjunk meg külsőleg (a __call első paramétere egy metódusnév a második egy array a paraméterekkel).

Innen megírni egy proxy osztályt már nem tart sokból, ha nem akarjuk túlmisztifikálni, akkor elég csak a call_user_func_array()-re gondolni, máris megvan a megoldás, persze a valóságban misztifikáljuk a dolgokat, de nem kell annyira előre szaladni.

Ha már ennyire előre léptünk, akkor láthatjuk, hogy a __call-on belül lehetőségünk van létrehozni egy pipeline-t, amiben meghívhatjuk az egyes extension-öket. Igen, csak eddig még semmit sem vettünk fel, illetve lehetőségünk sincs rá sehol, hogy funkcionalitásokat toljunk be a service-be. Vagy mégis?

Az alap WebService osztályban már leve volt egy ServiceDescriptor() metódus, ami egy ServiceDescriptor instance-t adott vissza, gyakorlatilag ennek segítségével szedtük össze már eddig is az operation-jeinket, miért ne használjuk továbbra is ezt? Következő lépésben létrehozhatunk X darab interface-t, amivel leírjuk az egyes kiegészítéseket (pl. egy paramétereket vizsgálónak lehet egy BeforeCall és egy AfterCall metódusa), plusz szükségünk lesz olyan konténerre, ami ezek tárolni tudja, csupán csak arra kell figyelnünk hogy egy ilyen konténer tudjon másolni másik konténerből is, hiszen akadhatnak olyan extension-ök, amelyeket az egész service-re akarunk alkalmazni, nem pedig metódusonként bohóckodni vele.

Kiegészítjük a service osztályunket egy method overload-dal:

public function ServiceDescriptor() {
$descriptor = parent::ServiceDescriptor();

$descriptor->Behavior()->AddErrorHandler(new ErrorHandler());
$descriptor->Behavior()->Operation("SOAPActionMethodName")->AddParameterInspector(new FilterAllRequestWithParameterXValueGreaterThanFive());
return $descriptor;
}

Mit csinálunk?
- adunk egy globális hibakezelőt a rendszerhez
- minden olyan kérésnél elszállunk fault-tal, amiben az X. paraméter értéke nagyobb, mint 5

Használhatóságban szerintem nem rossz, szerintetek? (A motorháztető alatt sem egy nagy cucc az egész, mégis. Viszont egy normális ServiceHost és ServiceHandler egyre jobban hiányzik a tisztább és szárazabb érzés miatt.)

Hozzászólások

(#1) Peter Kiss


Peter Kiss
senior tag
LOGOUT blog

[ értesítő ]

(#2) Peter Kiss


Peter Kiss
senior tag
LOGOUT blog

+ beépítve annak a lehetősége, hogy a nyers XML kérést és választ meg tudjuk nézni (SimpleXMLElement)
+ kiszedve a Web MVC infrastruktúrából minden, routing-gal lekezelve, hogy jó handler-hez kerüljön a végrehajtás, így már szebb lett a dolog (http://localhost/mymvc/valami.svc?wsdl, illetve már nem Controller a Service).

További hozzászólások megtekintése...
Copyright © 2000-2024 PROHARDVER Informatikai Kft.