Fórum Root.cz

Hlavní témata => Vývoj => Téma založeno: web_tonda 28. 03. 2018, 11:11:54

Název: Webove MVC - jak správně provázat Routes a Controllery u RESTu
Přispěvatel: web_tonda 28. 03. 2018, 11:11:54
Ahoj,programuji jednoduchou CRUD aplikaci, a v podstate poprve se to snazime udelat tak aby to byl REST interface, narazil jsem ale na par problemu v navrhu.


Predstavme si ze mame table Users a table Posts (fk=user.id). z takovyho schemata mi vyplynuly nasledujici controllery (jsou hodne granularni) v ramci takovych routes.

get_user_controller - "GET xxx/users/:userid"
post_user_controller - "POST xxx/users/:userid"
put_user_controller - "PUT xxx/users/:userid"
delete_user_controller - "DELETE xxx/users/:userid"


get_post_controller - "GET xxx/posts/:postid"
post_post_controller - "POST xxx/posts/:postid"
put_post_controller - "PUT xxx/posts/:postid"
delete_post_controller - "DELETE xxx/posts/:postid"

potud se to zda pekny a fajn (valna vetsina tutorialu na netu to nejak takhle prezentuje), JENZE nasleduje tahle vec - chcete udelat one-to-many relation ve smyslu users-post (pac posty maj fk k userum) - routes jsou jeste rekneme v poradku (snad?)

"GET xxx/users/:userid/posts/:postid"
"POST xxx/users/:userid/posts/:postid"
"PUT xxx/users/:userid/posts/:postid"
"DELETE xxx/users/:userid/posts/:postid"

JENZE nasleduje ten velky problem - jak na controllery? opravdu bych mel spravne napsat sadu 4 novych controlleru? neporusuje to dry, nemel bych spis mit mene controlleru a parametrizovat je vice? Co kdyz budu chtit pridat dalsi table? dalsi 4 controllery?

A ted to nejhorsi, co kdyz muj user table ma 6 one-to-many relations napriklad s tably - comments, books, movies, posts, friends, etc - musim pro kazdou takovou resource udelat 4, opakuji 4 nove controllery? to bych potom na na ten user table s 6fk tably, mel panecku 24 controlleru a 24 novych routes - neni to proboha priserne moc? neni problem to udelat ale zda se mi ze takove reseni neskaluje a co je nejhorsi v zadnym tutorialu co jsem videl okolo RESTu, i po googleni na stack overflow, nebylo vysvetelene jak tohle spravne a modularne udelat pri relacich one-to-many a many-to-many.

Chapu rest spravne? Je mozne ze to delam od zakladu blbe.

Diky za jakekoliv rady, jsem totalni novacek.
Název: Re:Webove MVC - jak správně provázat Routes a Controllery u RESTu
Přispěvatel: mejvas 28. 03. 2018, 12:14:48
Mel bys mit strukturu:
user_controller
 action_get
 action_post
 action_put
 action_delete

post_controller
 action_get
 action_post

atd..
Název: Re:Webove MVC - jak správně provázat Routes a Controllery u RESTu
Přispěvatel: mejvas 28. 03. 2018, 12:59:01
JENZE nasleduje ten velky problem - jak na controllery? opravdu bych mel spravne napsat sadu 4 novych controlleru? neporusuje to dry, nemel bych spis mit mene controlleru a parametrizovat je vice? Co kdyz budu chtit pridat dalsi table? dalsi 4 controllery?

A ted to nejhorsi, co kdyz muj user table ma 6 one-to-many relations napriklad s tably - comments, books, movies, posts, friends, etc - musim pro kazdou takovou resource udelat 4, opakuji 4 nove controllery? to bych potom na na ten user table s 6fk tably, mel panecku 24 controlleru a 24 novych routes - neni to proboha priserne moc? neni problem to udelat ale zda se mi ze takove reseni neskaluje a co je nejhorsi v zadnym tutorialu co jsem videl okolo RESTu, i po googleni na stack overflow, nebylo vysvetelene jak tohle spravne a modularne udelat pri relacich one-to-many a many-to-many.

"GET xxx/posts"
post_controller/action_get_posts -> Vypis bude vsechny zaznamy z tabulky posts

"GET xxx/users/:userid/posts"
user_controller/action_get_posts -> Vypis vsech posts pro uzivatele xy.



Název: Re:Webove MVC - jak správně provázat Routes a Controllery u RESTu
Přispěvatel: pra 28. 03. 2018, 13:10:04
Kód: [Vybrat]
"GET xxx/posts/:postid"
"GET xxx/users/:userid/posts/:postid"

Maji tyhle dve routy vracet stejnou odpoved?
Jestli ano tak proc ta druha existuje?
Jestli ne tak potrebuju lip vysvetlit usecase.
Název: Re:Webove MVC - jak správně provázat Routes a Controllery u RESTu
Přispěvatel: DK 28. 03. 2018, 13:32:03
Kód: [Vybrat]
"GET xxx/posts/:postid"
"GET xxx/users/:userid/posts/:postid"

Maji tyhle dve routy vracet stejnou odpoved?
Jestli ano tak proc ta druha existuje?
Jestli ne tak potrebuju lip vysvetlit usecase.

1. SELECT * from posts WHERE post_id = :postid
2. SELECT * from posts WHERE post_id = :postid AND user_id = :userid


Defakto neni nutne ten druhy delat, nicmene je beznou praxi delat vsechny CRUD endpointy
Název: Re:Webove MVC - jak správně provázat Routes a Controllery u RESTu
Přispěvatel: Natix 28. 03. 2018, 13:55:27
A co takhle?

Kód: [Vybrat]
GET /users
GET /users/:userid

GET /posts
GET /posts?userid=:userid
GET /posts/:postid
Název: Re:Webove MVC - jak správně provázat Routes a Controllery u RESTu
Přispěvatel: DK 28. 03. 2018, 14:11:25
A co takhle?

Kód: [Vybrat]
GET /users
GET /users/:userid

GET /posts
GET /posts?userid=:userid
GET /posts/:postid

Pokud se bavime o zavislostech, takhle by to nemelo byt. Properties v GET parametrech se pouzivaji pro filtraci / razeni (tj treba GET /posts?sort=title,ASC, nebo GET /posts?filter.name=lorem*)
Název: Re:Webove MVC - jak správně provázat Routes a Controllery u RESTu
Přispěvatel: pra 28. 03. 2018, 14:48:56
Kód: [Vybrat]
"GET xxx/posts/:postid"
"GET xxx/users/:userid/posts/:postid"

Maji tyhle dve routy vracet stejnou odpoved?
Jestli ano tak proc ta druha existuje?
Jestli ne tak potrebuju lip vysvetlit usecase.

1. SELECT * from posts WHERE post_id = :postid
2. SELECT * from posts WHERE post_id = :postid AND user_id = :userid


Defakto neni nutne ten druhy delat, nicmene je beznou praxi delat vsechny CRUD endpointy

Takze by to slo vyresit jen routovanim obou requestu na stejny controller i akci a ignorovanim userid.
API by zustalo kompletni a pocet kontroleru i akci by rostl linearne s poctem tabulek.
Název: Re:Webove MVC - jak správně provázat Routes a Controllery u RESTu
Přispěvatel: none_ 28. 03. 2018, 15:03:41
Defakto neni nutne ten druhy delat, nicmene je beznou praxi delat vsechny CRUD endpointy

Nemyslim si, ze delat vsechny CRUD je beznou praxi a uz vubec asi ne dobrou praxi. Pokud ten endpoint neni potreba, tak bych ho rozhodne nedelal.

A jeste jeden komentar. Pokud POST endpoint ma vytvaret zaznamy, tak by nemel prijimat ID jako parametr. To ID by melo byt unikatni a klient nema sanci zjistit, jaky ID je nebo neni. Beznou praxi je, aby tento endpoint vratil nejaky identifikator prave vytvoreneho zaznamu.
Název: Re:Webove MVC - jak správně provázat Routes a Controllery u RESTu
Přispěvatel: gll 28. 03. 2018, 15:24:53
Nechceš raději použít framework, který řeší vazby a url řeší za tebe, standardním způsbem?
Název: Re:Webove MVC - jak správně provázat Routes a Controllery u RESTu
Přispěvatel: ZAJDAN 28. 03. 2018, 15:54:51
Nechceš raději použít framework, který řeší vazby a url řeší za tebe, standardním způsbem?
přesně tak....já doporučuju Ruby On Rails....sám si tím teď procházím a CRUD/REST je tam vyřešen parádně
pro člověka s programátorskými znalostmi to bude stíhačka, když to začíná chápat i taková lama jako já! :_)
Název: Re:Webove MVC - jak správně provázat Routes a Controllery u RESTu
Přispěvatel: gll 28. 03. 2018, 16:20:51
Rails je dobrá volba. Když používáte ORM, tak máte vazby, validace atd. už popsané v modelech. API vytvoříte téměř zadarmo.
Název: Re:Webove MVC - jak správně provázat Routes a Controllery u RESTu
Přispěvatel: nudar 28. 03. 2018, 16:31:53
Koukám že tady nikdo neodpověděl tazateli na to na co se ptal - já to ještě pro jistotu jednou napíšu aby to bylo jasnější co tazatel chtěl.

když máte uri "POST xxx/users/" - je to jasný - voláte něco jako user.POST_controller
když máte uri "POST xxx/posts/" - opět je to jasný - voláte něco jako post.POST_controller

jenže když máte například získat všehny posty daného usera, uri může vypadat nějak takhle "GET xxx/users/:userID/posts", jakej controller na to z výše vyjmenovaných zavoláte? Ha? Žádnej - protože žádnej z výše uvedených tohle nedokáže zpracovat.

můžete udělat novej controller kterej bude pracovat s novým parametrem v URI, JENŽE bude tento controller z modelu User? (jasně, uri začíná "/users/:userID tak User) A NEBO ten controller bude z modelu POST, protože přece ta resource která se vrací je jen seznam vyfiltrovaných postů - a nebo uděláte úplně novej model? HA? (schválně neodpovím)

Odpovědi typu "místo microframeworků použij framework který to řeší za tebe" nebudu komentovat - očividně pracuje s frameworkem, kde si tohle má udělat sám, a pokud tomu nerozumí je to dobrá cesta se to naučit.
Název: Re:Webove MVC - jak správně provázat Routes a Controllery u RESTu
Přispěvatel: Ondrej Nemecek 28. 03. 2018, 18:27:05
Neznám kanonickou implementaci RESTu (a určitě by stálo by se do nějaké dobré implementace podívat, ideálně za použití stejných nástrojů jako používá tazatel), nicméně to routování tam je IMHO mimo jiné taky proto, že lze více url mapovat na stejný kontroler. Jinak je otázka, zda jsou vůbec ty endpointy pro vazby potřeba? Nestačí mít entity jen pro vlastní entity a pracovat s kolekcemi?

Jinak v některých framweorcích je skutečně REST API zdarma, je generované automaticky. Tam by se šlo taky inspirovat.
Název: Re:Webove MVC - jak správně provázat Routes a Controllery u RESTu
Přispěvatel: mejvas 29. 03. 2018, 07:40:08
jenže když máte například získat všehny posty daného usera, uri může vypadat nějak takhle "GET xxx/users/:userID/posts", jakej controller na to z výše vyjmenovaných zavoláte? Ha? Žádnej - protože žádnej z výše uvedených tohle nedokáže zpracovat.

můžete udělat novej controller kterej bude pracovat s novým parametrem v URI, JENŽE bude tento controller z modelu User? (jasně, uri začíná "/users/:userID tak User) A NEBO ten controller bude z modelu POST, protože přece ta resource která se vrací je jen seznam vyfiltrovaných postů - a nebo uděláte úplně novej model? HA? (schválně neodpovím)

Tazateli jsem na toto odpověděl hned na začátku.
"GET xxx/users/:userID/posts" zpracovává user_controller::action_get_posts není potřeba na to vytvářet žádný nový kontroller ani model. Opravdu není potřeba znovu objevovat kolo.
Název: Re:Webove MVC - jak správně provázat Routes a Controllery u RESTu
Přispěvatel: gll 29. 03. 2018, 14:38:57
jenže když máte například získat všehny posty daného usera, uri může vypadat nějak takhle "GET xxx/users/:userID/posts", jakej controller na to z výše vyjmenovaných zavoláte? Ha? Žádnej - protože žádnej z výše uvedených tohle nedokáže zpracovat.

můžete udělat novej controller kterej bude pracovat s novým parametrem v URI, JENŽE bude tento controller z modelu User? (jasně, uri začíná "/users/:userID tak User) A NEBO ten controller bude z modelu POST, protože přece ta resource která se vrací je jen seznam vyfiltrovaných postů - a nebo uděláte úplně novej model? HA? (schválně neodpovím)

Tazateli jsem na toto odpověděl hned na začátku.
"GET xxx/users/:userID/posts" zpracovává user_controller::action_get_posts není potřeba na to vytvářet žádný nový kontroller ani model. Opravdu není potřeba znovu objevovat kolo.

to podle mě není REST. Správně odpověděl Natix. Url by měly být jen ve tvaru /resources nebo resources/id + nějaké parametry.
Název: Re:Webove MVC - jak správně provázat Routes a Controllery u RESTu
Přispěvatel: ttt 29. 03. 2018, 15:27:42
Pokud se bavime o zavislostech, takhle by to nemelo byt. Properties v GET parametrech se pouzivaji pro filtraci / razeni (tj treba GET /posts?sort=title,ASC, nebo GET /posts?filter.name=lorem*)

Filtrace podle user_id není filtrace?
Název: Re:Webove MVC - jak správně provázat Routes a Controllery u RESTu
Přispěvatel: mesius 29. 03. 2018, 16:39:37
jenže když máte například získat všehny posty daného usera, uri může vypadat nějak takhle "GET xxx/users/:userID/posts", jakej controller na to z výše vyjmenovaných zavoláte? Ha? Žádnej - protože žádnej z výše uvedených tohle nedokáže zpracovat.

můžete udělat novej controller kterej bude pracovat s novým parametrem v URI, JENŽE bude tento controller z modelu User? (jasně, uri začíná "/users/:userID tak User) A NEBO ten controller bude z modelu POST, protože přece ta resource která se vrací je jen seznam vyfiltrovaných postů - a nebo uděláte úplně novej model? HA? (schválně neodpovím)

Tazateli jsem na toto odpověděl hned na začátku.
"GET xxx/users/:userID/posts" zpracovává user_controller::action_get_posts není potřeba na to vytvářet žádný nový kontroller ani model. Opravdu není potřeba znovu objevovat kolo.

to podle mě není REST. Správně odpověděl Natix. Url by měly být jen ve tvaru /resources nebo resources/id + nějaké parametry.

1. Pokud se nepletu, tak autor se neptal na to, co je a není RESTful, ale jak vytvářet MVC pattern vůči jednotlivým
routes.
2. RESTful API se nedefinuje tím, jakým způsobem se předávájí parametry v URL. I když existují good practises i v tomto směru, které podporují to co jsem napsal.

https://stackoverflow.com/questions/671118/what-exactly-is-restful-programming
https://blog.mwaysolutions.com/2014/06/05/10-best-practices-for-better-restful-api/

a tak dale...
Název: Re:Webove MVC - jak správně provázat Routes a Controllery u RESTu
Přispěvatel: BoneFlute 29. 03. 2018, 22:30:30
když máte uri "POST xxx/users/" - je to jasný - voláte něco jako user.POST_controller
když máte uri "POST xxx/posts/" - opět je to jasný - voláte něco jako post.POST_controller

jenže když máte například získat všehny posty daného usera, uri může vypadat nějak takhle "GET xxx/users/:userID/posts", jakej controller na to z výše vyjmenovaných zavoláte? Ha? Žádnej - protože žádnej z výše uvedených tohle nedokáže zpracovat.
Závolá se user.POST_controler s filtrem, že se mají vrátit posty.

To url mi přijde ošklivé, takové neRESTové.

A už tu bylo řečeno, že POST by měla být akce kontroleru (respektive dá se to rozdělit, ale ne mechanicky podle metod).