Jaki Kotlinowy stack teraz polecacie ?

1

Hej, skończyłem backend i apkę androidową, którą robię od jakiegoś czasu. Powiedzmy, że to wersja MVP z podstawowymi funkcjonalnościami. Apka androidowa wchodzi zaraz na wersję beta na sklep, polityki prywatności i regulamin mam ogarnięty od radcy prawnego, także czas na beta testy wśród szerszej grupie znajomych i jakieś tam próby marketingu.

Do kolejnej wersji, już powiedzmy MVP++ mam listę nowych ficzerów i zaraz będę zaczynał implementować, ale zanim ..
Chciałbym ten backend trochę porefaktorować, bo mimo, że ta apka jest po to, aby może coś zarobić, to też jednak staram się napisać to jak najlepiej.

Obecnie backend to monolit w kotlinie, przy użyciu springa mvc na tomcacie z postgresem i vavrem. Także trochę rak a trochę ok, bo jednak nie mam rzucania wyjątkami :D Po prostu tak mi było najszybciej napisać MVP i taki był cel.

Kolejna wersja to nadal będzie monolit w kotlinie, bo nie ma sensu robić z tego mikroserwisów. Zastanawiam się jednak czy springa mvc nie zmienić na pure FP springa lub ktora lub cokolwiek innego ? Zamiast vavra może arrow kt ? Bazę chce mieć relacyjną, bo w części "Query" mam sporo joinów między tabelami i no sprawdza mi się relacyjna baza.

Może będę dodatkowo aplikował rabbita, bo część systemu mogę ogarniać asynchronicznie.

Apkę deplojuję na elasticbean stalku.

Z góry dzięki za rady (nie ukrywam, że wzywam @jarekr000000).

3

Jeśli chcesz na tym zarabiać, to sprzedaż > technologia. Każda wprowadzona złożoność będzie kosztować Cię dodatkowy czas - słusznie, że odrzuciłeś mikroserwisy. Nie wiem czy w tym kontekście też nie odrzuciłbym pure-FP frameworków i innych cudeł. Powinieneś używać to, co dobrze znasz i dojrzale zważyć, unikać onanizmu technicznego, bo po prostu Twoim zadaniem jest $$$, a nie nauka technologii.

2

ArrowKt nigdy nie wykorzystałem komercyjnie. Nawet mi na razie nie przyszło do głowy. Co więcej nawet w moich hobby projektach... wywaliłem. Jak już bym miał użyć arrowkt... to pewnie napisałbym w Scali. (scalaz, cats), może nawet ZIO.
Co do reszty stacku:
spring webflux (goły, bez beanów) sprawdza mi się dobrze.
Podobnie kotlin ktor - trochę psioczyłem na ten projekt, ale już mi się podoba. Nie wszystko jest super czyste, ale i tak kilka razy lepiej niż spring webflux.

Jeśli masz bazkę SQL to wiadomo JOOQ. Kotlin ma swój framework exposed - pooglądałem i postanowiłem trzymać się od niego z daleka.
Wykorzystuje też JDBI - prymitywne, ale w cięzkich kobyłach z zastaną bazą SQL sprawdza się nieźle.

0

@jarekr000000: a jako DB co polecasz ? Ja wiem, że to zależy, ale tak jak napisałem - ja wziąłem sql, ponieważ widoki pozwalają mi fajnie ogarnąć jakieś zapytania o raporty, statystyki itd. I zapewne ORM nie, a co zamiast tego ? JOOQ ?

2

Sam nie testowałem ale http4k wygląda w miarę ok, z tym, że dalej jest to niepopularne i każda nowa osoba prawdopodobnie nie będzie tego znać. I można sobie gadać, że to tylko framework. Ale wymasterowanie czegoś trochę czasu zajmuje.

Dość popularny jest jeszcze vert.x toolkit.

Ale ja osobiście mam już dosyć reactive stacks ze względu na to, że ludzie nie umieją tego używać, nie chce już mi się tego sprzątać. No i zazwyczaj jest to przerost formy nad treścią.

Odsyłam do talka Pana Nurkiewicza o reactive lessons learned.

0

@jarekr000000:
Tak sobie pooglądałem jakieś konfy o JOOQ i wygląda spoko. Tylko to co mnie zastanawia ..

Jak używasz tego z pure webfluxem to mimo wszystko korzystasz z tych generatorów klas ?

Co do reaktywności to nakładasz na JOOQ-repo jakiegoś executora ?

I jak z transakcjami ? Bo też sporo osób mówiło, że JOOQ nieprzystosowane do tego i ono nie jest do użycia na 100% projektu tylko jako część obok jakiegoś ORMa w miejscach do którego się nadaje.

0
Bambo napisał(a):

I jak z transakcjami ? Bo też sporo osób mówiło, że JOOQ nieprzystosowane do tego

Można prosić jaśniej? Jako użytkownik JOOQ nie rozumiem tego pytania

2
Bambo napisał(a):

Jak używasz tego z pure webfluxem to mimo wszystko korzystasz z tych generatorów klas ?

tak

Co do reaktywności to nakładasz na JOOQ-repo jakiegoś executora ?

tak

I jak z transakcjami ? Bo też sporo osób mówiło, że JOOQ nieprzystosowane do tego i ono nie jest do użycia na 100% projektu tylko jako część obok jakiegoś ORMa w miejscach do którego się nadaje.

tego nie rozumiem. JOOQ doskonale prosto ogarnia transakcje - https://www.jooq.org/doc/3.13/manual/sql-execution/transaction-management/
spoko to działa, bo nie ma co się tam zepsuć ( w odróżnieniu od moich ukochanych adnotacji).

Fakt, że jak ktos lubi udziwnienia typu @Transactional to będzie mu dziwnie, (btw. na pewno mozna też JOOQ spiąć z JTA i mieć tego Transactional (też w linku), ale to nie moja bajka).
Dla dziwnych ludzi, którzy nieważne co robią, to zawsze chcieliby pisać w springu - od jakiegoś czasu robię eksperyment -https://github.com/neeffect/nee
nie używam tego nigdzie, i to tylko eksperyment: czy da się (w miarę) czysto zasymulować magię springa w kotlinie?

0

A jak JOOQ radzi sobie z transakcjami, jeśli jest odpalany na WebFlux? Przypadkiem nie trzyma kontekstu transakcji w ThreadLocal?

1
Charles_Ray napisał(a):

A jak JOOQ radzi sobie z transakcjami, jeśli jest odpalany na WebFlux? Przypadkiem nie trzyma kontekstu transakcji w ThreadLocal?

Zasadniczo nie ( z tego co wiem). Choć istnieje możliwość powiązania z wątkiem:
https://github.com/jOOQ/jOOQ/blob/main/jOOQ/src/main/java/org/jooq/impl/ThreadLocalTransactionProvider.java

Defaultowy https://github.com/jOOQ/jOOQ/blob/main/jOOQ/src/main/java/org/jooq/impl/DefaultTransactionProvider.java tego nie ma.
U mnie generalnie wszystko * co używa ThreadLocal wstępu nie ma (nawet jak nie korzystam z WebFlux) - dlatego odpadł Exposed jakiś czas temu (cichaczem sobie wrzucał i wyciągał z ThreadLocal).

(*) Dopuszczam korzystanie z ThreadLocal w aspektach typu monitoring.
No i czasem jakiś klient oczywiście technologię mi narzuci i wtedy też idę kod z ThreadLocalem w d...

0

@jarekr000000:
Jeszcze jedna sprawa. Jak konwertujes Future do Mono ?

Coś w tym stylu ?

fun <T> doInExecutor(executor: Executor, f: () -> T): Mono<T> {
    val completableFuture = CompletableFuture<T>()
    executor.execute { completableFuture.complete(f()) }
    return Mono.fromFuture { completableFuture }
}

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