Coyote 2.0: reguły routingu w bazie danych

0

To co zamierzam opisać, użyte jest w obecnej wersji Coyote. Nieśmiało sugeruję aby wykorzystać to również w nowej wersji, chyba że ktoś ma inny pomysł :)

Problem:

4programmers.net ma pełno dynamicznych stron takich jak /Pomoc, /Forum/Python, /Kontakt itp. Skąd system ma wiedzieć do którego kontrolera ma przekierować żądanie?

W aplikacjach opartych o wzorzec MVC definiujemy routing. Określamy jaki kontroler i akcja ma być uruchomiona w skutek wywołania odpowiedniej ścieżki (np. /Praca czy /Mikroblogi). Część konfiguracji może być oczywiście określona w pliku konfiguracyjnym. Co z resztą? W Coyote mamy tabelę page, która zawiera m.in. ścieżkę, tytuł strony, słowa kluczowe, opis oraz kontroler czy akcja. Niemal każda podstrona w serwisie ma odzwierciedlenie w rekordzie tabeli page. Tak więc routing wyszukuje żądaną ścieżkę w bazie danych jeżeli nie może jej znaleźć w pliku. Dzięki temu URL

Takie rozwiązanie ma kilka zalet:

  • Możliwe jest wyświetlenie hierarchii stron (strony macierzyste, potomkowie)
  • Proste zbudowanie mapy strony w XML
  • Możliwość blokowania dostępu do danej strony określonym grupom użytkowników
  • Licznik wizyt każdej podstrony w serwisie
  • Możliwość definiowania słów kluczowych, opisu i innych ustawień (osobno dla każdej podstrony w sewisie)
  • W bazie danych "trzymane" są powiązania pomiędzy stronami (tj. w której stronie znajduje się link do drugiej strony)
  • W przypadku zmiany nazwy strony, możemy "trzymać" starą wersję URL (i przekierować na nowy adres)
  • Tagi przypisane są do danej strony. Dzięki temu możemy grupować oferty pracy czy wątki na podstawie tagu
  • Informacja o obserwowanych stronach, wątkach czy ofertach pracy w jednej tabeli (po prostu klucz obcy do tabeli page_id)
1

IMO:

Czemu plik konfiguracyjny/baza danych? Nie widziałem chyba nigdzie (poza coyote) konfiguracji routingu w bazie danych, a konfiguracja całego routingu w pliku konfiguracyjnym nie jest piękna :P. W większości systemów/frameworków jakie widziałem, konfiguracja routingu jest w kodzie - czyli najpierw kod rejestruje routing a później z nich korzysta. Wydaje mi się że trzymanie routingu w bazie/konfiguracji to overengineering, skoro dużo większe systemy niż coyote tak robią i radzą sobie dobrze.

Ale tak naprawdę to gdzie są rejestrowane routy jest mniej ważne. Ważne jest to żeby:

  • w kodzie nie było żadnych urli hardcodowanych (a zdarzają się obecnie :P) - jeśli trzeba gdzieś umieścić url, kontroler/widok może najwyżej wywoływać jakąś funkcję url_for(controller, action).
  • w drugą stronę (url -> kontroler + akcja + parametry) mapping powinien robić framework.
  • routing powinien wiedzieć o argumentach, wyciąganie czegokolwiek z $_GET w kontrolerze jest słabe i niszczy prawie cały sens używania MVC.

W Coyote mamy tabelę page, która zawiera m.in. ścieżkę, tytuł strony, słowa kluczowe, opis oraz kontroler czy akcja. Niemal każda podstrona w serwisie ma odzwierciedlenie w rekordzie tabeli page. Tak więc routing wyszukuje żądaną ścieżkę w bazie danych jeżeli nie może jej znaleźć w pliku. Dzięki temu URL

IMHO page i page_matrix to najgorsza część bazy :P. Jeśli rezygnujemy z pisania supergenerycznego frameworka (a takie jest główne założenie), w pełni statyczny routing w kodzie jest w 100% wystarczający.
Zresztą m.in przez page są dramatyczno-dziwne problemy np. przy przenoszeniu wątków albo implementacji dzielenia wątków/przenoszenia postów ;).

Jeszcze problem jaki widzę to wsteczna kompatybilność - fajnie by było gdyby obecne urle dalej działały (tzn. no muszą działać, nie ma innej opcji).

0

@msm: napisz coś więcej. Jak to ma wyglądać? Jest sobie żądanie do ścieżki /Delphi, /Kontakt, /Pomoc czy /Forum/Coyote/Test. Sk to są przykładowe, dynamiczne strony. Skąd system ma wiedzieć do jakiego kontrolera/akcji przekazać żądanie?

0

@Adam Boduch: w Magento jest to zrobione na takiej zasadzie:

b0ee31abbf.png

I albo nie zrozumiałem problemu, albo faktycznie mogłoby to znaleźć zastosowanie także tutaj :P

0

@Patryk27: wydaje mi się że zrozumiałeś problem :) Obecnie w Coyote wygląda to podobnie jednak @msm ma inny pomysł tylko nie do końca rozumiem jak miałoby to działać...

0

Chyba nie ma lepszego pomysłu niż trzymanie ścieżek w bazie danych. Przynajmniej do tych stron tworzonych dynamicznie. Ze statycznymi (typu panel użytkownika) nie ma problemu. Z forum też nie byłoby problemu, ponieważ forum znajduje się pod subdomeną.

Ale co ze ścieżką /Foo, czy /Foo/Bar? System nie wie gdzie przekierować dane żądanie ponieważ te strony zostały utworzone dynamicznie. Poza tym jest kilka zalet takiego rozwiązania (co przytoczyłem w pierwszym poście). Szczególnie parsowanie linków wewnętrznych w treści. System znajdując taki link jest w stanie "zobaczyć" czy taka strona rzeczywiście istnieje i "ładnie" sformatować link w oparciu o tytuł danej strony. Dodatkowo mamy listę powiązanych ze sobą stron. Nie muszą to być wątki na forum, ale też oferta pracy czy artykuł.

Kurcze, trzymanie ścieżek dynamicznych w tabeli nie jest idealnym rozwiązaniem. Ale brak mi lepszego pomysłu... :/

0

@Adam Boduch nie piszę w PHP więc może dlatego nie do końca rozumiem w czym rzecz. Przecież nikt nie tworzy dynamicznych "stron" tylko co najwyżej dodaje dane do bazy. Załóżmy że mamy link 4programmers.net/Kompedium/XX i teraz mamy konkretny kontroler który łyka wszystko z Kompedium. Tenże kontroler ze ścieżki odczytuje sobie XX czyli identyfikator danych z bazy które ma wyświetlić. Kontroler pobiera dane dla tego identyfikatora a następnie populuje Widok tymi danymi.
Gdzie tu jest potrzeba jakiegos routingu?

0

@Adam Boduch nie piszę w PHP więc może dlatego nie do końca rozumiem w czym rzecz. Przecież nikt nie tworzy dynamicznych "stron" tylko co najwyżej dodaje dane do bazy

Nie? :P

http://4programmers.net/Edit/NoweLepszeKompendiumWiedzy

I taką nową stronę bezpośrednio pod / może dodac każdy zarejestrowany użytkownik. Dobrze ze chociaż anonimowi nie mogą :P.

Załóżmy że mamy link 4programmers.net/Kompedium/XX i teraz mamy konkretny kontroler który łyka wszystko z Kompedium. Tenże kontroler ze ścieżki odczytuje sobie XX czyli identyfikator danych z bazy które ma wyświetlić

Tak by było fajnie, ale nie da się tego zrobić tak, żeby wszystkie istniejące obecnie urle dalej działały - bo obecnie działa to tak jak wyżej.

0
Shalom napisał(a):

@Adam Boduch nie piszę w PHP więc może dlatego nie do końca rozumiem w czym rzecz. Przecież nikt nie tworzy dynamicznych "stron" tylko co najwyżej dodaje dane do bazy. Załóżmy że mamy link 4programmers.net/Kompedium/XX i teraz mamy konkretny kontroler który łyka wszystko z Kompedium. Tenże kontroler ze ścieżki odczytuje sobie XX czyli identyfikator danych z bazy które ma wyświetlić. Kontroler pobiera dane dla tego identyfikatora a następnie populuje Widok tymi danymi.
Gdzie tu jest potrzeba jakiegos routingu?

Tych kategorii mamy sporo. Mamy więc /Delphi, /C itp. Mamy też strony takie jak /Kontakt czy /Pomoc. Te strony są tworzone dynamicznie, można też tworzyć kolejne. Obecnie jeżeli coyote nie może odnaleźć danej strony w regule routingu, to sprawdza w bazie danych czy istnieje strona - np. Pomoc. Jeżeli tak, to odczytuje ustawienie kontrolera i wywołuje go.

Dodatkowo w bazie danych trzymane są zależności danej strony. Każda strona może mieć rodzica oraz potomków. Dzięki temu możemy generować drzewo kategorii. Dlatego też mamy takie URL-e jak: /Delphi/Artykuły/Foo/Bar (jak widzisz - jeden tekst jest zagnieżdżony w drugim).

Chyba że zrobimy tak:

Plik z konfiguracją routingu:

http://4programmers.net/Forum/.* => forum
/Mikroblogi/.* => mikroblogi
/Praca/.* => praca
.* (czyli wszystko pozostałe co nie pasuje do pozostałych wzorców) => moduł wiki

Pytanie tylko jak parsować linki wewnątrz postów. Obecnie jak napisze http://4programmers.net/Forum/Coyote/260418-coyote_20_reguly_routingu_w_bazie_danych to da to taki efekt: Coyote 2.0: reguły routingu w bazie danych

Można zrobić tak, że parser będzie sprawdzał linki i porównywał z regułami routingu. Jeżeli uzna że link to link do posta, to sprawdza czy istnieje taki wątek i pobiera jego tytuł. Jeżeli nie będzie mógł dopasować URL-a do żadnej reguły, to sprawdzi w module wiki, czy istnieje taka strona. Można tutaj zastosować wzorzec strategii.

0

Ale zauważ że nowy kontroler /reguła kontrolera jest potrzebna tylko jeśli widok jest inny. /C i /Delphi niczym się oczywiście nie różnią wiec nie potrzeba innego kontrolera.

Jak parsowac linki? Może np restowe API do pobierania danych na temat podstrony oparte o taką samą logikę kontrolerów?

0

ja bym był za tym, aby wszystkie urle byly w bazie danych na wzór tego jak jest w Magento. Daje to ogromne możliwości modyfikacji. Tworzy się reguły routingu z jakimś priorytetem, a następnie patrzy się do jakiego wyrażenia dany url pasuje i wtedy wykonać dany kontroler z daną akcja, z danymi parametrami. Nie będzie wtedy wyjątków takich, że część adresów jest w bazie, część jest statyczny routingiem. Po prostu tworzy się nowy modul o a wie Contact, do którego dodaje się w migrqcji nowe wyrażenie do routingu.

1 użytkowników online, w tym zalogowanych: 0, gości: 1