[python] Roboti, REST, Flask?

Honza Javorek mail na honzajavorek.cz
Středa Září 16 11:40:06 CEST 2015


Ahoj,

Petr byl rychlejší. Rozdíl mezi GET, PUT, POST, atd. je v tom, že je přesně
ve specifikaci řečeno, co může nebo nemůže způsobit, např. opakovaným
zavoláním.

> HTTP REST uz je striktnejsi a popisuje presnejsi pouziti i DELETE, PUT,
PATCH, etc.

To není úplně přesné. HTTP je protokol a má svoje specifikace. REST je
nějaký styl architektury aplikace, se slovesy v HTTP nemá až tak moc
společného a nemusíme jej tady asi ani řešit (jo, vím že jsem to sám dřív
taky motal do sebe). Úplně pro tento případ postačí, pokud se budeme držet
toho, co nám radí (či specifikací přikazuje?) HTTP samotné.

Jsou na to v zásadě dvě RFC:

- základ v https://tools.ietf.org/html/rfc7231
- PATCH dodělaný a dolepený v http://tools.ietf.org/html/rfc5789

Nebát se číst specifikaci! Je to lidsky psané. Tady přesně se mluví o tom,
jaký je rozdíl mezi metodami, co jaká znamená a co přináší jejich použití a
je tam i pěkná tabulka: https://tools.ietf.org/html/rfc7231#section-4.1

GET je jen čtení, akce, která neublíží. Když budeš při GET mazat, projede
ti odkazy Google nebo kdokoliv jiný a smaže ti cokoliv co tam zrovna mažeš.
Tzn. vše podle specifikace předpokládá, že GET by neměl nic měnit. Taky to
znamená, že cokoliv co je GET se může kdekoliv po cestě kešovat.

PUT je nějaká změna, která je tzv. idempotentní, tzn. když ji pošleš
několikrát za sebou, tak se pak už nic nezmění. Typicky když něco nastavíš
na "vypnuto", tak stejný request můžeš poslat třeba tisíckrát po sobě a ta
věc bude mít nakonec stále "vypnuto". Abych dal protipříklad, nehodí se to
na věci, které jsou např. "přepni" ve stylu vypínače na světlo - když ho
pošlu jednou tak vypne, podruhé zapne, atd. Aby to mělo danou vlastnost,
implementace PUTu vypadá tak, že sestrojíš celou novou reprezentaci a tou
"přeplácneš" tu starou. Takový "replace". Když v cíli nic není, tak se to
při PUTu na dané URL vytvoří, tzn. vhodné i pro vytváření, pokud víš "ID"
předem.

DELETE maže, následně by po něm nemělo nic zůstat.

PATCH je speciál na částečné změny, tzn. že pošleš nějaký diff, kterým
řekneš co se má změnit a server to podle toho diffu nějak změní. Záruky
neveliké, všelijaké, a tak dále.

POST je nějaká změna, která ale nemusí být nutně idempotentní. Je to
základní způsob, jak udělat změnu stavu na serveru. Nedá se to kešovat a
tak dále.

Pozn.: HTML formát a klienti kolem něj (typicky prohlížeče atd.) podporují
často jen GET a POST. S tím si vystačí, protože to hlavní co je potřeba
rozlišit je kešovat/nekešovat a bezpečné/nebezpečné. POST má myslím ve
specifikaci někde taková "zadní vrátka", že kromě toho, že je určen k tomu
co jsem napsal výše, tak může být použit i na "cokoliv jiného". V důsledku
je tedy i HTML s formulářem na mazání osedílaným přes POST udělán správně
podle HTTP specifikace. Klidně můžeš udělat všechno přes POST a bude to
jakože správně, ale tím se připravuješ o to, že GET je pro čtení
efektivnější. Udělat ale všechno v GET místo POST je špatně a koleduješ si,
protože označuješ "nebezpečné" akce jako "bezpečné" (stejně tak s
kešovatelností).

Sorry že jsem se tak rozepsal. Hlavně mi moc nevěřte a přečtěte si to
raději v té specifikaci. Já jsem taky jenom člověk, ale tam je to prostě
vysvětlené a napsané, tak jak to má být.

Honza


2015-09-16 9:37 GMT+02:00 Petr Viktorin <encukou na gmail.com>:

> 2015-09-16 7:45 GMT+02:00 Petr Blahos <petrblahos na gmail.com>:
> > Ještě poznámečka: Pokud bude GET měnit vnitřní stav aplikace, a povede k
> > němu
> > nějaký link, tak ho Google klidně navštíví při indexování :-) Nebo jak
> měl
> > kdysi takové
> > to přednačítání odkazů...
>
> Je psáno [1], že GET nemá měnit stav, a spousta nástrojů to předpokládá.
> Kromě robotů to předpokládají třeba různé keše nebo load balancery. Ty
> sice teď asi nepoužíváš, ale neměl bys zapomenout na to, že *učíš*
> lidi používat HTTP. Nauč je to prosím správně.
>
> [1] ve specifikaci HTTP:
> http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
> > the GET and HEAD methods SHOULD NOT have the significance of taking an
> action other than retrieval. These methods ought to be considered "safe".
>
> > 2015-09-15 22:33 GMT+02:00 Ales Zoulek <ales.zoulek na gmail.com>:
> >>
> >> Technicky rozdil mezi PUT a GET je minimalni. Je ale konvence, aby akce
> >> odpovidala tomu HTTP "slovesu".
> >>
> >> Uplnym minimem je rozliseni mezi GET a POST. Tzn. GET (narozdil od POST)
> >> by nemel menit vnitrni stav serveru, pouze ten stav cist.
> >>
> >> HTTP REST uz je striktnejsi a popisuje presnejsi pouziti i DELETE, PUT,
> >> PATCH, etc.
> >>
> >> Pokud nemas vylozene duvod to nedodrzovat, tak je lepsi se te konvence
> >> drzet.
> >>
> >>
> >> A.
> >>
> >> On Tue, Sep 15, 2015 at 9:54 PM Marek Nožka <marek na tlapicka.net> wrote:
> >>>
> >>> Ahoj
> >>>
> >>> On Tue, 15 Sep 2015 08:40:33 +0200 Honza Javorek <mail na honzajavorek.cz
> >
> >>> wrote to Konference PyCZ <python na py.cz>:
> >>>
> >>> > Jestli mají posílat nějaké informace a těma měnit stav na serveru,
> tak
> >>> > musíš použít i něco jiného než GET, pokud se budeme bavit aspoň o
> >>> > samotném
> >>> > blbém HTTP, když už ne o RESTu.
> >>>
> >>> To je právě to, co nechápu. Pokud vezmu množinu jednoduchých akcí jaký
> je
> >>> rozdíl mezi
> >>>
> >>> GET /123acb/krok
> >>>
> >>> a mezi
> >>>
> >>> PUT
> >>> id = "123abc",
> >>> akce = "krok"
> >>>
> >>> Chápu, že když chci poslat nějaký větší objem dat je PUT jistě lepší,
> ale
> >>> pokud jde jen o jednoduché povely, co mi PUT nebo DELETE přináší za
> >>> výhodu?
> >>>
> >>> > Já bych ti to klidně nějak zkusil namodelovat, ale k tomu by se
> hodila
> >>> > komplet pravidla té hry a možné stavy, do jakých se lze dostat a jak
> se
> >>> > do
> >>> > nich lze dostat.
> >>>
> >>> Pravidla jsou zatím velice jednoduchá:
> >>> Server umístí hráče na hrací pole a ukáže jim, kde je poklad. V každém
> >>> kole
> >>> lze provést jednu z akcí:
> >>>   * otoč se o 90° doleva
> >>>   * otoč se o 90° doprava
> >>>   * udělej krok
> >>>
> >>> Cílem je, za co nejmenší počet kol dosáhnout cíle. Server upozorní
> pokud
> >>> by klient šel do zdi nebo pokud chtějí dva hráči vejít na stejné
> políčko.
> >>> Počítám, ale časem s rozšířením pravidel o časované bomby, střílení,
> >>> dobíjení
> >>> a vybíjení baterií, práce v týmu. Uvidíme jak nám to půjde.
> >>>
> >>> Díky
> >>>       Marek
> _______________________________________________
> Python mailing list
> python na py.cz
> http://www.py.cz/mailman/listinfo/python
>
> Visit: http://www.py.cz
>
------------- další část ---------------
HTML příloha byla odstraněna...
URL: <http://www.py.cz/pipermail/python/attachments/20150916/a7b00fb2/attachment.html>


Další informace o konferenci Python