HTTPlug egy év távlatában

Már majdnem egy év telt el, amióta a HTTPlug első verziója kiadásra került, így gondoltam ideje egy kis vissza, illetve előretekintésnek: mi van mögöttünk, mi vár még a projektre.

Ha még nem hallottál róla: a HTTPlug egy HTTP kliens absztrakció PHP nyelven, ami mögött a PHP HTTP csoport áll. A projekt célja, hogy a HTTP alapú szoftverkönyvtáraknak ne kelljen konkrét implementációra épülnie, elkerülve ezzel az úgynevezett “vendor lock-in” által okozott hátrányokat. Egyszerűbbé teszi továbbá a függőségek kezelését, hiszen nem kell minden könyvtárnak saját HTTP kliens függőséget definiálni és telepíteni, nem beszélve azokról az esetekről, amikor ezek esetleg ezek még inkompatibilisek is egymással (gondoljunk csak a Guzzle 5 és 6 esetére).

Magán az absztrakción kívül a projekt tartalmaz még már ismert HTTP kliens implementációkhoz (úgy mint Guzzle, Buzz, stb) tartozó adaptereket is, így mindenki használhatja a jól bevált kedvencét.

Egy kis történelem

Az egész egy (Eric Geloen által írt) Ivory HTTP Adapter nevű könyvtárral kezdődött. Talán a nevéből kitalálható: már létező HTTP kliensekhez biztosított HTTP adaptereket. A PSR-7 akkoriban még messze nem volt kész (de már így is legalább a harmadik-negyedik teljesen újraírt verziót élte meg), ami magát a könyvtárat rendkívül érdekessé és hasznossá tette, sok fejfájást okozott azonban Eric-nek, hogy rendszeres változtatások miatt gyakorlatilag minden alkalommal újra kellett írnia a kód egy részét. De megérte, hiszen összehasonlítva az akkoriban elérhető hasonló szoftverekkel sokkal több funkció állt a rendelkezésünkre.

A sok kódváltozás mellett azonban egy másik komoly árat is kelett ezért fizetni: nagy számú függőség telepítését. Gyakorlatilag csak idő kérdése volt, hogy valaki javasolja a projekt több kisebb darabra szedését, ami hamar meg is történt. Az innen induló beszélgetések eredménye képpen szinte órákon belül létrejött a PHP HTTP csoport.

HTTP adapt…kliens absztrakció

Eleinte rettenetesen izgatottak voltunk, főleg mivel a csoport megalakulása után nem sokkal PSR-7 néven publikálták a HTTP üzenetekre vonatkozó standardot. Ennek eredménye képpen egy elnyúló, kicsit kapkodós, ötletekkel teli tervezési fázist, nem egyszer teljes koncepció váltást élt meg a projekt.

Az egyik legnagyobb ilyen koncepcióváltás akkor következett be, amikor az adapterek szétszedése helyett elkezdtünk inkább magán az absztrakción dolgozni. Szerettünk volna egy minimális, stabil alapot létrehozni, így sajnos rengeteg beépített funkciótól meg kellett válnunk (konfiguráció a kérés objektumban, HTTP metódushívások, stb). Az eredmény: egyetlen interfész egy (PSR-7 kérés objektumot paraméterként elfogadó) send metódussal. No de hogy ne csak kidobáljuk a dolgokat, de adjunk is hozzá, követte ezt egy második interfész, ami aszinkron kéréseket támogat, ez szolgált később a plugin rendszer alapjául.

Miután gyakorlatilag az egész projektet feje tetejére állítottuk és adapterek helyett inkább kliens absztrakción dolgoztunk, szerettünk volna egy nevet is találni a projektnek: így jött létre a HTTPlug.

Packageception

Mint említettem elég sok funkciót ki kellett venünk az absztrakció megalkotásához, de nem szerettük volna ezeket teljesen ki is dobni, így ezeket kisebb szoftverkönyvtárakban helyeztük el. Ahogy egyre több funkciót hoztunk át (vagy implementáltunk saját magunk), úgy nőtt és lett egyre kezelhetetlenebb a csomagok száma, arról nem is beszélve, hogy az alkalmazásaink composer.json fájljai PHP HTTP függőségekkel lettek tele. Elég sokáig rágódtunk ezen a problémán: tanulva a korábbiakból nem akartunk mindent egy csomagba visszatenni, de látszott, hogy az “egy csomag, egy funkció” logika sem vált be, így próbáltunk rálelni az arany középútra. Végül két nagy kategóriába osztottuk a csomagok nagy részét és ezeket egy-egy csomagba foglaltuk össze:

  • message: Ide kerültek a HTTP üzenetekkel kapcsolator eszközök (autentikáció, kódolás, tömörítés, factory-k, stb)
  • client-common: Néhány hasznos kliens implementáció (Batch kliens, HTTP metódus kliens, sync/async emulátorok), valamint a plugin rendszer került ebbe a csomagba

Ugyanakkor hogy a sok függőséget elkerüljük, a fenti csomagokba csak olyan kód került, aminek nincs külső (nem PHP HTTP) függősége, minden egyéb kód maradt a saját csomagjában.

Visszajelzések

Elég sok, többségében pozitív visszajelzést kaptunk a közösségtől, de természetesen érkeztek azért kritikák is. Ezekre igyekeztünk mint lehetőségre tekinteni, hogy a HTTPlug használatát felhasználóbarátabbá tudjuk tenni.

Az egyik leginkább negatív visszajelzést kapott része a projektnek az a discovery réteg, azon belül a Puli (igen, a magyar Puli kutyáról kapta a nevét) használata, ami saját magát “egy univerzális csomag kezelő rendszer”-nek titulája. Valójában az egyes keretrendszerekbe való csomagintegrációt könnyíti meg nagyon. Esetünkben ez a telepített HTTP kliensek és factory-k integrációját jelentette. Azonban a felhasználói visszajelzések szerint a Puli telepítése és beállítása nem volt egy leányálom, ezért úgy döntöttünk, hogy a használtatát opcionálissá tesszük: aki akarja használhatja, de a discovery réteg használatához nem szükséges.

Talán azt is pozitívnak könyvelhetjük el, hogy több nagy projekt (a teljesség igénye nélkül: Geocoder, Mailgun SDK, FOS HTTP Cache) is elkezdte használni a kliens absztrakciót. Külön köszönet jár ezért a csoport egyik tagjának (Tobias Nyholm), mert ezek a projektek javarészt a ő kontribúciójának köszönhetően álltak át HTTPlug használatára (akár egyedi adapter megoldásról, vagy a legtöbb esetben egy konkrét kliens implementáció használatáról).

Az előttünk álló út

Bár a legnépszerűbb kliensekhez megírtuk az adaptereket, mégis a legideálisabb az volna, ha a kliensek maguk implementálnák az általunk készített interfészeket. Ennek érdekében elkezdtük kidolgozni egy lehetséges standard (PSR) részleteit. Mivel az absztrakció már most is elég egyszerű és stabil, így ez javarészt a specifikáció, illetve a tervezés során hozott döntések részletes leírásából áll. Remélhetőleg ezzel hamar végzünk és a jelenleg hatályos FIG szabályok szerint alakíthatunk egy munkacsoportot, aminek a feladata a standard utolsó átvizsgálása és FIG-nek való bemutatása lesz.

Sajnos azonban van egy rossz hír is: a standardban nem fog szerepelni az aszinkron támogatás. Ennek oka az, hogy szükség lenne egy event loop/promise standardra is, amit a HTTPlug maga ugyan tartalmaz, de nem lenne túl jó ötlet azt magával a HTTP kliens standarddal együtt publikálni, arról nem is beszélve, hogy már van egy csoport (PHP Asynchronous Interoperability Group), amelyik ezen dolgozik. Jelenleg a lehetőségeket vizsgáljuk, de remélhetőleg hamarosan elkezdhetünk dolgozni az aszinkron standardon is.

Mivel augusztus óta a csoport felel a Guzzle HTTP kliensért is, a standard elfogadása esetén (az eredeti szerzővel egyetértésben) a Guzzle a lehető leghamarabb támogatni fogja azt.

Maintenance promise

Bár a visszajelzések pozitívak voltak, sok ember kifejezte aggodalmát aziránt, hogy visszafelé inkompatibilis változás történik, megszűnik a támogatás, esetleg deprekáljuk a projektet, pláne most, hogy dolgozunk a PSR-en. Ahogy már korábban említettem, az interfészek már most is stabilak (köszönhetőek a hosszú béta tesztelési fázisnak), így komoly változásoktól nem kell tartani. Ami a támogatást illeti: amennyiben a standardot jelenlegi formájában elfogadják, a projekt 100%ban kompatibilis lesz vele. Amennyiben nem, a támogatás megszűnésétől akkor sem kell tartani, mivel elég nagy projektek használják már most is.

Összegzés

Véleményem szerint elég izgalmas első év volt ez a projekt életében, és amennyire én látom, még legalább ennyi tennivaló van előttünk. Talán az események kissé lelassultak (pláne a PSR miatt), de a projekt továbbra is aktív és az is marad, remélhetőleg még jó hosszú ideig.

httplug  php  http