@Bragi czy mam się zainteresować czymś jeszcze oprócz REST dla RoR?
Dobra firma która to napisze ;]
A tak na poważnie to https://github.com/spastorino/rails-api, ja bym w ogole wybral sinatre, albo goliath + Grape ale to już moje osobiste preferencje.
Ja nie mam czasu się za bardzo rozpisywać, ale pracowałem (i właściwie teraz pracuję) nad systemami złożonymi z wielu małych aplikacji i trzeba pamiętać, że takie podejście rozwiązuje problem monolitycznych aplikacji, ale wprowadza całą gamę nowych problemów. Kilka słów o sednie problemu na wikipedii: http://en.wikipedia.org/wiki/Fallacies_of_Distributed_Computing (część z tych punktów ma małe znaczenie w omawianym przypadku, ale pokazują błędny sposób myślenia).
Musisz też pamiętać, że budowanie rozproszonych aplikacji będzie miało znacznie większy koszt na początku.
Nie chcę zniechęcać do tego pomysłu, bo sam jestem zwolennikiem takich rozwiązań, ale często kiedy mówi się o takim podejściu, to ludzie zapominają o problemach jakie to ze sobą niesie.
Szkoda, że nie mam czasu na rant dotyczący grape
Co do sinatry, to bardzo ją lubię, ale jednak sinatra bez żadnych dodatków robi tylko część tego co Railsy jeżeli chodzi o obsługę HTTP, więc trzeba rozważyć na ile się zna ten temat i samemu chce robić to co railsy już mają rozwiązane. wycats kiedyś napisał tekst o tym jakie są plusy używania railsów do API, ale nie mogę tego znaleźć, jak ktoś ma linka, to poproszę o wklejenie.
No grape dodałem z racji konieczność bo Goliath od wersji 1.0 nie ma routingu już i trzeba to gdzieś rozwiązać. Można na wyższym poziomie jak nginx czy haproxy
Szkoda, że nie mam czasu na rant dotyczący grape ;)[/quote]
No to weź to napisz - chętnie poczytam, bo jak na mój ogląd Grape wygląda interesująco, ale chętnie poznałbym negatywną opinię na jego temat.
Szkoda, że nie mam czasu na rant dotyczący grape ;)[/quote]
No to weź to napisz - chętnie poczytam, bo jak na mój ogląd Grape wygląda interesująco, ale chętnie poznałbym negatywną opinię na jego temat.[/quote]
Właściwie to muszę doprecyzować. Źle zrozumiałem gotara i po tym dopisku o goliath rozumiem już o co chodzi. Szczerze mówiąc nie bardzo interesowałem się goliathem do tej pory, więc wydawało mi się, że chodzi o goliath + rails lub sinatra i na to jeszcze grape. Jeżeli grape ma być jedyną aplikacją na goliacie, to już trochę bardziej sensowne, aczkolwiek też nie do końca podoba mi się ta idea (pomijam już fakt, że goliath miał przez długi czas skopaną obsługę HTTP, chyba przy Connection: close, pewnie to już rozwiązali, ale wtedy ludzie się na to rzucili BO WEBSCALE I ASYNC!!111 nie patrząc na nic innego).
Co do samego grape’a, to gem sam w sobie nie jest tragiczny. Największy problem jaki z nim mam, to fakt, że jeżeli używa się go z railsami albo sinatrą, to dodaje jakiegoś bezsensownego DSLa zupełnie oderwanego od reszty aplikacji. Sam gem nie wnosi prawie nic co by mi się przydało przy robieniu API, a te rzeczy, których domyślnie nie ma (np. obsługa version) można bardzo prosto załatwić dodając gemy, które rozszerzają railsy zamiast budować cały oddzielny framework. Jak się używa grape’a to dostajesz kilka nowych metod, a reszta to reimplementacja tego co jest w railsach. Łącznie ze wszystkimi tego konsekwencjami, typu np. jest tam jakieś rescue_from, ale czy działa tak samo jak w railsach? Być może, a może nie. Dodatkowo, jeżeli aplikacja jest w railsach, to team zna już railsy. No i teraz zamiast po prostu wykorzystać to co wszyscy znają, dodaje się zupełnie nowy DSL, który w README wygląda bardzo fajnie, ale jak będzie trzeba obsłużyć jakieś edgecase’y, to trzeba będzie się uczyć jak to ustrojstwo można rozszerzyć (no i tutaj uwaga uwaga, jako, że to jest DSL i nie wiadomo jak w środku napisany, to nie wiadomo czy są rzeczy typu before_filter, albo czy tak jak w kontrolerach można po prostu zrobić include jakiegoś modułu i rozszerzyć jakieś metody). Być może da się podmontować jakiś middleware, ale tego nie wiem, bo w README nie ma o tym ani słowa.
Jedyna rzecz, której na pewno bym używał, to metoda errors, ale do tego z reguły dorzucam halt: https://github.com/strobecorp/strobe-rails-ext/blob/master/lib/strobe/action_controller/haltable.rb - łatwiej jest dodać 20 linijek niż cały nowy framework.
Ciekawa opinia - ważne jest to zastrzeżenie, że jeśli używa się Railsów, to Grape’a nie ma sensu używać. I wydaje mi się, że faktycznie w tym scenariuszu “same” Railsy dadzą radę.
Ale jeśli chcemy mieć dużo lżejszą aplikację, która nie potrzebuje wszystkich dobrodziejstw Railsowych, ale potrzebujemy jakiejś fasady do API, to użycie Grape’a jest lepsze np. niż użycie Sinatry, właśnie ze względu na ten DSL. Osobną kwestią jest oczywiście dojrzałość tej biblioteki - to pewnie wyjdzie w praniu, ale patrząc na liczbę forków to chyba nie jest tak źle.
W przypadku lekkiego API bym też bym użył Sinatry Ale tutaj rzeczywiście jest trochę większy sens używnia grape’a
… to wyłączamy wszystkie komponenty Rails oprócz tych których naprawdę potrzebujemy. Właśnie otake railsy walczyli autorzy 3.0.
https://gist.github.com/1942658
A co do meritum wątku, to bardzo polecam notkę o odchudzaniu klas Activerecord:
… to wyłączamy wszystkie komponenty Rails oprócz tych których naprawdę potrzebujemy. Właśnie otake railsy walczyli autorzy 3.0.
https://gist.github.com/1942658[/quote]
Pozwolę się nie zgodzić - powiem szczerze, że w Railsach wkurza mnie routing. W sumie doszedłem do wniosku, że separowanie routera od kontrolera, to był bardzo zły pomysł. Nawet żeby zorientować się w tym, jakie są parametry muszę zajrzeć do innego pliku, niż ten, w którym one są dostępne. To jest idiotyczne. Podejście Sinatry/Grape’a jest tutaj dużo lepsze.
To samo się tyczy AcitveRecord - uważam, że podejście DataMappera, gdzie wprost definiujesz dostępne pola też pozwala znacznie szybciej zorientować się co jest dostępne. Summa summarum powstają narzędzia do anotowania klas modelu, ale nie musiałyby powstawać gdyby pola były wprost zdefiniowane.
A co do linku do “jednoplikowych” Railsów - wyobraź sobie, że zaczynam ludzi uczyć Rubiego i pokazuję taki kod - mówiąc, to sobie wpiszcie żeby dostać aplikację “Hello World”. Może nie jest to hello world w JSP, ale imho niedaleko temu do Javy. Zamiast tego mogę w Sinatrze zrobić:
[code=ruby]require ‘rubygems’
require ‘sinatra’
require ‘sinatra/reloader’ if development?
get ‘/’ do
erb :index
end
post ‘/’ do
@message = "Witaj " + params[:name]
erb :result
end[/code]
i wytłumaczyć każdą linijkę. Bez porównania.
To rozmawiamy o uczeniu ludzi Railsów czy o specjalizowanych rozwiązaniach? Bo co najmniej jeden z nas bezpardonowo offtopuje/derailuje/robi irrelewantne argumenty.
Wrzucasz gista do jednoplikowej aplikacji w Railsach to Ci odpisuję, że w Sinatrze to jest dużo prostsze i przejrzystsze. Argument ze studentów może nie jest specjalnie istotny w kontekście budowania złożonej aplikacji komunikującej się po RESCie, ale jest niewiele mniej związany z dyskusją niż Twoje zachwyty nad jednoplikową apką raislową.
Dywagacje na temat AR vs DM to faktycznie offtop pokazuje jednak filozofię Railsów, która w pewnym momencie zaczyna przeszkadzać.
[quote=Tomash]A co do meritum wątku, to bardzo polecam notkę o odchudzaniu klas Activerecord:
http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/[/quote]
To samo, ale lepiej pokazane jest w książce Avdiego http://objectsonrails.com/#sec-1
Przykłady Codeclimate (jak sądzę ze względu na skrótowość) nie unikają jednego z podstawowych błędów - twardego powiązania klas poprzez wywołanie metod klasowych (User.new, etc.)
BTW - ile to ma związku z meritum to niech każdy już sam oceni
IMHO i Sinatra i Railsy mają swoje miejsce. Lubię pisać w obu frameworkach i na pewno podoba mi się prostota sinatry, ale jak zaczynasz pisać w sinatrze, to musisz być w miarę pewien, że ta aplikacja pozostanie względnie mała. Jak sie rozrośnie, to zaczną sie problemy z czasem bootowania (a w sinatrze nie ma żadnego reloadowania kodu domyślnie) i innymi rzeczami, do których ten framework nie jest po prostu przystosowany. I wtedy albo jak najszybciej rozbijas na mniejsze aplikacje albo przepisujesz na railsy.
Są jeszcze ludzie, którzy w takim wypadku piszą swój własny framework oparty na sinatrze, ale takie przypadki pominę (mam taką teorię, że goście od padrino mieli appkę, która zaczęła się rozrastać tak, że sinatra nie dawała rady i tak bardzo chcieli brnąć dalej, że napisali padrino)
Wszystko fajnie, ale flejm był o przydatność Grape’a a nie Sinatry.
@halgrim Istnieje już coś takiego jak API do bazy danych - jest to najczęściej binarny protokół
Nie wiem czemu kiedy uczymy się systemów rozproszonych chcemy je wszędzie stosować. Choć w sumie z każdą nową wiedzą taki jest.
Pomysł chyba wygląda tak: zrobimy API do bazy, będą możliwe tylko te operacje, które zatwierdzimy. A my pod spodem będziemy mogli wymienić storage na jaki chcemy!
Implementacja wydaje się prosta: aplikacja w Rails, Sinatrze, Javie. Do tego biblioteki, które po HTTP wykonują operacje.
Co się stanie jeśli jedna z aplikacji potrzebuje zmiany w schemacie? Trzeba dodać to do aplikacji API, dodać do bibliotek, które z tego API korzystają, zaktualizować wszystkie aplikacje.
Ktoś odkrywa, że brakuje walidacji na jednym z modeli - wartości jednak nie powinny być dowolne tylko z pewnego zakresu. Dodawana jest walidacja do implementacji API. Trzeba by ją dodać do bibliotek. Trzeba znów zaktualizować wszystkie aplikacje.
Jedna z aplikacji nie powinna mieć dostępu do wybranych danych. Trzeba wprowadzić system autoryzacji - efektywnie partycjonując dane według aplikacji. Dzięki temu zmiana w jednej aplikacji nie wymaga wymiany bibliotek w pozostałych.
Wszystko działa ale teraz mamy za duże opóźnienie przy każdym zapytaniu. Gdzie ten czas schodzi… Każde zapytanie do bazy danych to 150ms? Przecież po protokole binarnym było 5ms!
@Bragi czy możesz polecić jakąś lekturę lub podesłać jakiś przykład (jak nie tutaj to na priv) jak zbudować dobre API? Mam tutaj na myśli strukturę/schemat komunikacji pomiędzy dwoma aplikacjami. Pewnie warto zadbać także o inne rzeczy niż przekazanie wersji, o których bez popełnienia kilku błędów podczas rozwoju aplikacji teraz nie pomyślę. Będę chciał dodać nową funkcjonalność i okaże się, że źle zbudowałem API i trzeba je przebudować. Chciałbym tego uniknąć, a niestety nie mam doświadczenia w budowaniu aplikacji rozproszonych.
Na pewno warto przeczytać RFC 2616, przydaje się wiedza jak to działa i jakie masz możliwości. Co do reszty, to Steve Klabnik polecał tą książkę: http://www.amazon.com/Building-Hypermedia-APIs-HTML5-Node/dp/1449306578. Ale nie czytałem, więc nie mam pojęcia czy jest dobra
Co do SOA i tematów powiązanych jeszcze, to ostatnio wpadło mi kilka rzeczy:
http://manning.com/rotem/ - podobno dobra, dopiero kupiłem, więc jeszcze nie mam zdania, jak przeczytam mogę wrzucić krótki opis
http://queue.acm.org/detail.cfm?id=1142065 - rozmowa z kimś od amazonu