Doktor Debugger i klinika kodu.
Odcinek 1: Not so RESTfull
Ten dzień zaczął się jak każdy inny: lista zadań, trochę kodu do przejrzenia, 10 razy więcej do napisania. Po szybkim uporaniu się ze spamem z Basecampa (to nie działa, tamto jest do zrobienia – w skrócie: nudy) przeszedłem do głównego zadania: implementacja REST-a.
Jak doskonale wiadomo REST jest spoko, Zend Framework jest spoko więc wszystko powinno iść jak z płatka. Niestety tylko w teorii…
Zgodnie z zasadą Kubusia Puchatka („myśl, myśl, myśl”) przerobioną dla potrzeb programistów („manual, manual, manual”) natychmiast sięgnąłem do dokumentacji Zend_Rest. O ile znajomość klasy Zend_Rest_Client jest zdecydowanie przydatna to zagłębienie się w Zend_Rest_Server było błędem…
Zachwycony prostotą implementacji w kilka minut skleciłem prosty serwer REST i klienta potrafiącego się z nim komunikować. W tym miejscu zaczęły się schody: Zend_Rest_Server zwracał kod XML, który nie odpowiadał moim wymaganiom (dodatkowo dopisywał informacje o tym, że to on generuje odpowiedź). Moja reakcja była bezlitosna: dziedziczenie i przeciążenie kilku metod generujących kod XML. Niestety to nie rozwiązało wszystkich moich problemów. W dalszym ciągu nie podobał mi się sposób komunikacji z serwerem i ogólnie kombinacje kiedy chciałem rozbudowywać system o większą ilość funkcjonalności. Straciłem czas, a jeszcze chciałem wyskoczyć na kebaba…
Niezadowolony z dotychczasowych wyników zdecydowałem się kolejny raz porozmawiać z Wujkiem Google. Tak właśnie dotarłem do Zend_Rest_Route i Zend_Rest_Controller. Klasy te były rozwiązaniem moich programistycznych problemów (i co za tym idzie zmniejszyły liczbę słów pospolicie uważanych za obelżywe). Sprowadzony na poprawną ścieżkę programistyczną, radośnie zacząłem implementować poszczególne funkcjonalności. Niemal sielankowe programowanie przerwał mi nieudany test komunikacji za pomocą HTTP DELETE. Wyjątek był jednoznaczny: serwer zwraca niepoprawnego XML-a.
W momencie kiedy poczułem lekki zapach debbugowania, przyniesiony z bryzą wytwarzaną przez wszędobylskie wiatraczki chłodzące komputery, natychmiast zamieniłem się z Doktora Debuggera.
Zleciłem biopsję kawałka kodu odpowiadającego za generowanie odpowiedzi. Bezlitosnym wzrokiem omiotłem próbkę programu, sprawdziłem każdy szereg lekko przestraszonych komend PHP. Po kliku minutach diagnoza była jednoznaczna: to nie BuggiusInCodus (bardzo popularna i dość łatwa do wyleczenia choroba kodu). Wiedząc, że sam mogę nie rozwiązać tego problemu zawołałem moich asystentów: CURL-a i LiveHTTPHeaders. W trójkę zaczęliśmy ze wszystkich stron oglądać pacjenta. To co odkryliśmy zaszokowało cały zespół: kod objawiał standardowe syndromy AcesusDenaidus (potocznie zwanego także błędem 403 – brak dostępu). Nikt nie znał przyczyny tego typu zachowania: uprawnienia w normie, poprawne reakcje w przypadku testów GET i POST.
Zacząłem wertować dokumentacje medyczną udostępnianą przez Wujka Google. Znalazłem przypadki bliskie i równocześnie bardzo odległe od problemu mojego pacjenta (np. AcesusDenaidus dla DELETE i PUT dla Apache z lekami zwiększającymi odporność typu WebDAV itp.). Po ciężkiej walce kilometrami tekstu dotarłem do rozwiązania:
<VirtualHost *:80>
ServerAlias subdomena.localhost
DocumentRoot /sciezka/do/srodowiska/na/localu/public
<Directory "/sciezka/do/srodowiska/na/localu/public">
Allow from all
</Directory>
</VirtualHost>
Szybko zleciłem operację na otwartych Vhostach. Pacjent po wybudzeniu natychmiast zaczął dobrze reagować na PUT i DELETE.
Przypisy:
- Podana konfiguracja stosowana jest w lokalnych środowiskach developerskich.
- Przed aktualizacjami w dokumentacji Zend Frameworka kontroler REST-a został „opisany” w 5 linijkach tekstu. Obecnie jest już dużo lepiej, wystarczającą ilość informacji możecie znaleźć w dokumentacji ZF (pod koniec dokumentu).