.

.

niedziela, 28 maja 2017

Filtrowanie client side

bukareszt
źródło: x3.cdn03.imgwykop.pl

Zmiany, zmiany. BUKA wychodzi z piwniczki (czy też - z aresztu ;) siedziała tam długo, więc krok ma trochę niepewny...) i rusza w świat. To znaczy: od dziś jest dostępna na github pages i prezentuje prawdziwe książki, a nie randomowe publikacje o tytułach w rodzaju Ergonomic Cotton Cheese, serwowane przez mock REST API. A wszystko za sprawą Firebase. Ale po kolei...

Do tej pory korzystałam z mock REST API, które uruchamiałam wyłącznie na localhost (żeby serwować je poza localhost, potrzebny byłby hosting node.js, którego nie mam). W związku z tym niemożliwe było hostowanie aplikacji, choćby na github pages właśnie, bo zasoby z API dostępne były tylko lokalnie. Potrzebowałam więc bazy książek na serwerze. Ponieważ zajmuję się front-endem, chciałam użyć jako API czegoś gotowego - wybór padł na Firebase (a dokładnie - moduł / produkt Realtime Database; Firebase to "kombajn", który oferuje dużo więcej).

Wykrystalizował mi się taki plan: dalej rozwijam aplikację na localhost z Gulpem i mock REST API, a wersję "produkcyjną", dla której bazą danych jest Firebase Database, umieszczam na github pages. Docelowo powinnam zatem mieć jeden kod, który będzie obsługiwał dwa środowiska - developerskie i produkcyjne.

Baza danych udostępniana przez Firebase okazała się... dość specyficzna. Odbiega ona od RESTtowych standardów, które poznałam do tej pory. Najważniejsze różnice:

  • w URLach do Firebase konieczny jest dopisek .json (na końcu), który wskazuje żądany format danych
  • w mock REST API content-type podawany jest jako nagłówek HTTP (jQuery domyślnie obsługuje to w AJAXie) - i na tej podstawie API wie, w jakim formacie ma wysłać dane
  • Firebase Database "nie lubi" danych typu Array, preferowanym typem jest Object; wprawdzie można do Firebase zaimportować kolekcję typu Array, jednak po wykonaniu POSTa do tejże kolekcji (i utworzeniu nowego itemu) Array zostanie automatycznie zmieniony (po stronie Firebase) w Object
  • w Firebase nie ma filtrowania danych jako takiego; w prostym przypadku (np. pobierz książki z gatunku reportaż) można je zasymulować przez sortowanie (orderBy z użyciem startAt, endAt, equalTo), ale multifiltowanie (np. pobierz książki z gatunku reportaż oraz wywiad, tylko wypożyczone) w ogóle nie jest dostępne

Po serii testowych requestów stało się jasne, że mój dotychczasowy kod tak "po prostu" nie obsłuży żądań wysyłanych i do mock REST API, i do Firebase. Aby możliwa była komunikacja z jednym i z drugim API, część kodu musiała zostać zmodyfikowana (dostosowana do każdego z API). Zmianom uległa warstwa modelu, dzięki czemu controller pozostał "nieświadomy" co do tego, z jakim silnikiem API ma do czynienia, jak to API działa.

Najistotniejsza różnica dotyczyła wspomnianego już filtrowania. Mock REST API filtruje dane server side, dzięki czemu client side dostaje gotowe dane, przefiltrowane według określonych kryteriów. Z uwagi na "upośledzenie" tej funkcjonalności w Firebase, konieczne stało się wprowadzenie filtrowania po stronie klienta (przeglądarki). Nie jest to może najbardziej optymalne i wydajne rozwiązanie, ale na obecne potrzeby wystarcza. (Nie spodziewam się, by moja - czy inna, przeciętna - domowa biblioteka liczyła miliony książek. Choć to bardzo nęcąca, przyjemna wizja... :)

Tak więc Firebase zwraca całą kolekcję książek, które w danym momencie "ma", a filtrowanie odbywa się client side. W ten sposób warstwa controllera nie zmienia się, a dostosowanie kodu do specyfiki mock REST API oraz Firebase pozostaje ograniczone do warstwy modelu (zamknięte w modelu).

Kod zawierający opisane powyżej zmiany dostępny jest w repozytorium projektu na osobnym branchu. Wersja aplikacji z wykorzystaniem Firebase Database - wciąż robocza - dostępna jest tutaj.

Kolejny krok to automatyzacja - na poziomie Gulpa - budowania aplikacji pod Firebase i mock REST API. Oraz ogarnięcie uwierzytelniania użytkownika w Firebase, tak aby dostęp do danych nie był publiczny. Ale to pieśń przyszłości. :)


PS
Gdyby ktoś zaznajomiony z Firebase czytał to i miał sugestie, co można zrobić inaczej, lepiej, to chętnie takowe przygarnę. :)


Brak komentarzy:

Prześlij komentarz