Čím v Go nahradit protocol buffers pro front-end?

hknmtt

Čím v Go nahradit protocol buffers pro front-end?
« kdy: 17. 01. 2023, 16:54:55 »
Po rokoch bezproblemoveho pouzivania gRPC a Protocol Buffers, v Go, som postupne prestal pouzivat gRPC v prospech obycajneho http, lebo 99% veci islo aj tak von na front-end, kde je kral json. Najprv som pouzival grpc-gateway, potom som prestal s gRPC uplne. Roky som pouzival PB na definovanie schem, ale narazam na problemy so serializaciou od prechodu z PB2 na PB3 a od prechodu z go-nativnej pb serializacie na guglacku, ktora sa ma dnes pouzivat a nativna je uz de facto deprecated.

Lenze narazam zase na problemy s u/int64 parsovanim, mimo prazdnych pointerov z PB3 ktore mi robia problemy, lebo PB2 a PB3 sa chovaju odlisne, tak ako aj nativna serializatia od goglackej. A proste uz mam toho dost a chcem sa PB zbavit kompletne.

Hladam preto alternativu a nejak moc neviem co. Som zvyknuty si proste definovat v proto subore interfejs cez service a rpc metody a do toho request a response spravy, vygenerovat si interfejs a implementovat. Ale neviem ze co ine mi to poskytne, okrem c'n'p ktore ma slabu podporu a penetraciu takze je to moc exoticke. Flatbuffers su zase strasne verbozne a su urcene primarne na ulozenie dat. Thrift som nikde na zivo ani nevidel.

Jedine co mi ostava je vykaslat sa na IDL a proste si manualne definovat vsetko, cim pridem o "mapu" systemu, ako som uz zvyknuty. Nehovoriac o tom, ze ked pride cudzi clovek tak bez .proto definicie si musi manualne prejst system aby porozumel co a ako. Kdezto v .proto definicii to ma hned na ociach vsetko.

Tak by ma skratka zaujimalo ako riesit http API(tzn hovorim o json komunikacii backendu a frontendu a nerenderuje sa ziadne html a podobne) dnes inak nez s protocol buffers?
« Poslední změna: 17. 01. 2023, 16:59:32 od Petr Krčmář »


alex6bbc

  • *****
  • 1 753
    • Zobrazit profil
    • E-mail
Re:Čím v Go nahradit protocol buffers pro front-end?
« Odpověď #1 kdy: 17. 01. 2023, 17:14:47 »
a co treba BSON, binarni format pro JSON.
moc to neznam, ale predpokladam, ze to bude setrnejsi na mnozstvi dat nez JSON
a jsou parsery pro Go i JS.

hknmtt

Go - problem parsovanie int64 v jsone
« Odpověď #2 kdy: 17. 01. 2023, 17:57:27 »
ono vlastne problem asi ani nie je v PB ako takom. ide len o to ako sa naparsuju spravy. kedze pouzivam proto json, tak ten vie naparsovat u/int64 spravne. ale zase naparsuje prazdne pole aj null rovnako, takze stracam informaciu o tom ci bol prijaty null alebo prazdne pole, napriklad, a vzdy dostanem prazdne pole(to bola zmena pri pb2 a pb3 a pre pb3 si vyzaduje wrappery, respektive field mask, co je proste "mental"). ked namiesto proto jsonu pouzijem zase normalny json parser, tak ten mi zase naparsuje spravne null a prazdne pole, ale zase skape na u/int64. Cize v podstate moj problem je v konencom dosledku len ten int64 kedze ostatne sa da mitigovat. co som pozeral alternativne json parsery pre go tak vsetky fejluju na tom int64 bez vynimky zatial. ten u/int64 vyslovene potrebujem len na par miestach(napriklad pre vlekost suboru kde uint32 mi robi 4GB limit, co je problem) takze teoreticky mozem prepisat vsekto na int32 a tie int64 manualne parastovat do a zo stringu asi, inak ma nic nenapada.

hknmtt

Re:Čím v Go nahradit protocol buffers pro front-end?
« Odpověď #3 kdy: 17. 01. 2023, 20:48:31 »
Koho by zaujimalo ako v Go riesit json a int64 tak som nasiel riesenie(treba si overtit ci funguje v danom enkoderi, nemusia to podporovat vsetky ale goccy a easyjson ano):

Kód: [Vybrat]
type Message struct {
Size uint64 `json:"size,string"` <---- ,string appendix
}

alex6bbc

  • *****
  • 1 753
    • Zobrazit profil
    • E-mail
Re:Čím v Go nahradit protocol buffers pro front-end?
« Odpověď #4 kdy: 17. 01. 2023, 20:53:57 »
tak pred parsovanim udelam z cisel string a mam po starostech a muzu posilat i 0xdeadbeef, bx1010001110, ox12345671234567.


Re:Čím v Go nahradit protocol buffers pro front-end?
« Odpověď #5 kdy: 18. 01. 2023, 10:25:03 »
My jsme naskočili později, takže přechod z v2 na v3 nás netrápí, zde neumím pomoci.
Každopádně možnost klasického JSON API na základě proto definice řešíme. Dokonce Protobuf používáme jako IDL na eventy a podobně.
V Go je nutnost používat google.golang.org/protobuf/encoding/protojson, to je občas na obtíž, pokud se tam připlete ne-proto objekt, který nesplňuje interface.
Souhlas, ze gRPC gateway je dost podivná. Každopádně nedávno jsem narazil na alternativní implementaci gRPC specifikace.
Je to od těch samých lidí, co udělali `buf` cli.
Vyklepu sem nějaké ty linky.

https://buf.build/blog/connect-a-better-grpc
https://connect.build/
https://github.com/bufbuild/connect-go
https://github.com/bufbuild/connect-web

A tady je hezká ukázka toho, jak gRPC funguje. Že to není žádná magie.
https://github.com/akshayjshah/grpc-demystified

hknmtt

Re:Čím v Go nahradit protocol buffers pro front-end?
« Odpověď #6 kdy: 18. 01. 2023, 11:42:20 »
My jsme naskočili později, takže přechod z v2 na v3 nás netrápí, zde neumím pomoci.
Každopádně možnost klasického JSON API na základě proto definice řešíme. Dokonce Protobuf používáme jako IDL na eventy a podobně.
V Go je nutnost používat google.golang.org/protobuf/encoding/protojson, to je občas na obtíž, pokud se tam připlete ne-proto objekt, který nesplňuje interface.
Souhlas, ze gRPC gateway je dost podivná. Každopádně nedávno jsem narazil na alternativní implementaci gRPC specifikace.
Je to od těch samých lidí, co udělali `buf` cli.
Vyklepu sem nějaké ty linky.

https://buf.build/blog/connect-a-better-grpc
https://connect.build/
https://github.com/bufbuild/connect-go
https://github.com/bufbuild/connect-web

A tady je hezká ukázka toho, jak gRPC funguje. Že to není žádná magie.
https://github.com/akshayjshah/grpc-demystified

s grpc a pb robim roky, len ako som pisal, problem je prave s jsonom. prvy problem bol medzi pb2 a pb3 kedy pb2 malo povinne a volitelne polia, pb3 uz to nema, co je dobre, ale zase berie prazdne pole a null ako rovnaku hodnotu, takze nemozno zistit, ci uzivatel neposlal ziadnu zmenu alebo chcel vyprazdnit pole. Na to zaviedli debilne field_mask.

Dalsi problem bol ze golang mal nativnu kniznicu pre pb, lenze ta nebola kompatibilna s google kniznicou, ktora sa stala casom popularnejsia a de facto ta nativna je deprecated. Okrem nekompatibility je tam problem s tym, ze ta nativna ma "emit defaults" switch kedy vide odoslat prazdne pole namiesto null, presny opak problemu na vstupe.

Treti problem je ze proto json vie naparsovat int64 a uint64 spravne. Cize json string naparsuje na datovy typ u/int64 a naopak.

No a moj problem bol ze som si presiel vsetkymi tymito stadiami a neustale riesil problemy jeden za druhym. Co sa grpc gateway tyka, to bolo v pohode, len mi vadilo na tom ze princip bol taky ze json -> unmarshal na pb objekt -> marshal na pb -> brana  -> unmarshal na proto objekt. Takze to v principe bolo neefektivne dost, ale funkcne.

Casom som to opustil, tak ako postupne vsetko. No a dnes uz som sa rozhodol pb dat doprec kompletne lebo grpc nepouzivam a pb mi robi viac skody nez uzitku. Hlavne tie bloatnute structy co to generuje, plne pointerov, wrapperov, mutexov a gzip definicii v globalnych premennych a podobne.

Takze idem do cisteho go kodu. Nemam nutnost riesit kompatibilitu s inymi jazykmi, takze proto schema mi chybat nebude zas moc. Nativny json, resp. pouzivam goccy teraz, vie spravne riesit omitempty a null vs prazdne pole/mapa... a tiez vdaka tomu triku hore aj u/int64 parsovanie.

Jedine o co som teraz prisiel je ze v proto som mal definovane aj sluzby a rpc ale na druhu stranu mam jeden http handler so switchom kde su definovane cesty(nepouzivam muxer) takze je to stale na jednom mieste.

Spravy asi presuniem do suborov s handlermi nech je to pokope a nie v jednom centralizovanom subore. Musim si akurat zvyknut po rokoch na novy postup. To je cele. Preto som sa pytal ako ludia riesia architekturu apiciek.

hknmtt

Re:Čím v Go nahradit protocol buffers pro front-end?
« Odpověď #7 kdy: 19. 01. 2023, 11:45:26 »
Nadviazem na povodnu otazku - odstranenim PB mi vznika problem ze do buducna je vsetko definovane len v kode, takze ja si nemam ako potom vygenerovat napriklad front-end api, mat prehlad o zozname url, aka url ma aku metodu a  request a response schemu, pretoze to je vsetko v kode a clovek musi manualne ist pozerat a hladat co a ako.

Takze to IDL mi bude chybat tak ci onak. Preto ma zaujimalo ake technlogie pouzivate namiesto PB?

Re:Čím v Go nahradit protocol buffers pro front-end?
« Odpověď #8 kdy: 19. 01. 2023, 15:29:40 »
Takze to IDL mi bude chybat tak ci onak. Preto ma zaujimalo ake technlogie pouzivate namiesto PB?

OpenAPI, ale to je děs. Neni to IDL, ale YAML peklo. Právě od toho prcháme na protobuf.

hknmtt

Re:Čím v Go nahradit protocol buffers pro front-end?
« Odpověď #9 kdy: 19. 01. 2023, 16:17:35 »
prave z PB sa generuje open api/swagger ako plugin do grpc gateway.

anyway, aktualne mam plne pod kontrolou backend aj front-end api takze nejaka dokumentacia ma netrapi a pre verejne api potom nieco zbuchat manualne nebude moc problem, jedine ak to bude velke, co zatial neplanujem.

Len pre info, akrualne som si spravil sturkturu ze mam jeden http server handler(ServeHTTP) kde robim len switch na metodu a dopytovanu cestu. podla get/post naparsujem argumenty na strruct a ten predam potom handleru ktory ma tvar(context, request) a vracia response objekt a error. response sa potom handlerom vrati klientovi ako json aj s headermi a spoj, ditto error. Kazdy handler ma svoj subor kde ma tiez definovazne request a response structy. Takze je to po kope a teda prakticky si staci otvorit ten "muxer", najst url a hned clovek moze prejst na handler kde vidi request aj response schemu. Je to kod, nie je to pre koncakov ale to mi netreba momentalne. Ono so as iani inak moc nejde ak clovek nepouziva IDL na autogenerovanie kodu proste.

Videl som aj ako chlapik robil to ze v mxueri vlastne mal definovane structy pre kazdu routu priamo pred volanim handleru, takze clovek videl komplet cel ustrukturu priamo v ServeHTTP() ale uz som zvyknuty mat to izolovane podla jednotlivych handlerov proste.