23
Университет Текарт

Контроллер Web-приложения на основе REST

Embed Size (px)

Citation preview

Page 1: Контроллер Web-приложения на основе REST

Ïîñòðîåíèå ñëîÿ êîíòðîëëåðà âåá-ïðèëîæåíèÿ

íà îñíîâå àðõèòåêòóðû REST

Ìàðêåòèíãîâàÿ ãðóïïà Òåêàðò

14 èþëÿ 2009 ã.

Университет Текарт

Page 2: Контроллер Web-приложения на основе REST

Университет Текарт

×òî ìû õîòèì îò ñëîÿ êîíòðîëëåðà

àáñòðàêöèÿ HTTP-çàïðîñà è îòêëèêà, êîìïåíñèðîâàíèåíåóäîáñòâ âñòðîåííîé ðåàëèçàöèè;

âîçìîæíîñòü ñáîðêè îáðàáîò÷èêîâ çàïðîñîâ èç îòäåëüíûõìîäóëåé (middleware-êîìïîíåíòû);

äèñïåò÷åðèçàöèÿ URL, ïðîñòàÿ ñòðóêòóðà íàáîðà ïðàâèëäèñïåò÷åðèçàöèè;

REST êàê íàèáîëåå óíèâåðñàëüíàÿ àðõèòåêòóðà.

Ïîñòðîåíèå ñëîÿ êîíòðîëëåðà âåá-ïðèëîæåíèÿ íà îñíîâå àðõèòåêòóðû REST 2

Page 3: Контроллер Web-приложения на основе REST

Университет Текарт

Àáñòðàêöèÿ HTTP-çàïðîñà è îòêëèêà

Net.HTTP.Request: ïàðàìåòðû çàïðîñà ÷åðåç èíäåêñèðîâàííûéäîñòóï, îáúåêòíûå uploads, upload â ìàññèâàõ ïîëåé.

$id = $request['id'];

$auth = $request->headers['Authorization'];

foreach ($request['upload'] as $line) { ... }

$stored = $request['upload']->copy_to($path);

Net.HTTP.Response: ðàáîòà ñ çàãîëîâêàìè îòêëèêà, body:ñòðîêà, èòåðàòîð, ôàéëîâûé îáúåêò.

$file = IO_FS::File($path);

return Net_HTTP::Response()->

status(Net_HTTP::OK)->

content_type(MIME::type_for_file($file))

body($file);

Ïîñòðîåíèå ñëîÿ êîíòðîëëåðà âåá-ïðèëîæåíèÿ íà îñíîâå àðõèòåêòóðû REST 3

Page 4: Контроллер Web-приложения на основе REST

Университет Текарт

Îáðàáîò÷èê çàïðîñîâ

Îáúåêò êëàññà, ðåàëèçóþùåãî ñòàíäàðòíûé èíòåðôåéñ:

interface WS_ServiceInterface {

public function run(WS_Environment $env);

}

Ðåçóëüòàò âûïîëíåíèÿ run() � Net.HTTP.Response.

WS.Environment:

åäèíñòâåííûé ñïîñîá îáìåíà èíôîðìàöèåé ìåæäóîáðàáîò÷èêàìè;

ìîæåò ïîðîæäàòü äî÷åðíèå îáúåêòû îêðóæåíèÿ,ïåðåîïðåäåëÿþùèå çíà÷åíèÿ îòäåëüíûõ ïàðàìåòðîâðîäèòåëüñêîé ñðåäû;

ïî óìîë÷àíèþ ñîäåðæèò $request òèïàNet.HTTP.Request.

Ïîñòðîåíèå ñëîÿ êîíòðîëëåðà âåá-ïðèëîæåíèÿ íà îñíîâå àðõèòåêòóðû REST 4

Page 5: Контроллер Web-приложения на основе REST

Университет Текарт

Middleware-êîìïîíåíòû

abstract class WS_MiddlewareService

implements WS_ServiceInterface {

protected $application;

public function __construct(WS_ServiceInterface $application) {

$this->application = $application;

}

}

çàïîìèíàåò ñëåäóþùèé îáðàáîò÷èê è âûçûâàåò åãî;

ìîæåò ìîäèôèöèðîâàòü environment, request, response.

Ñòàíäàðòíûå êîìïîíåíòû: êîíôèãóðàöèÿ, ïîäêëþ÷åíèå êÁÄ, êåøèðîâàíèå, ñåññèè, àâòîðèçàöèÿ, ðîóòèíã àäðåñîâ.

Ïîñòðîåíèå ñëîÿ êîíòðîëëåðà âåá-ïðèëîæåíèÿ íà îñíîâå àðõèòåêòóðû REST 5

Page 6: Контроллер Web-приложения на основе REST

Университет Текарт

Îáùàÿ ñòðóêòóðà ïðèëîæåíèÿ

WS.Middleware.*

REST Applications

Status

Environment

Config

Cache

ORM

Auth

REST

FrontNewsPhotoAPI

öåïî÷êà îáðàáîò÷èêîâ èç

ñòàíäàðòíûõ ìîäóëåé;

ïðîåêò � íàáîð ìàêñèìàëüíî

íåçàâèñèìûõ ïðèëîæåíèé;

êàæäîå ïðèëîæåíèå � äîìåí èëè

êàòàëîã ïåðâîãî óðîâíÿ;

äèñïåò÷åðèçàöèÿ àäðåñîâ � âíóòðè

ïðèëîæåíèÿ.

Ïîñòðîåíèå ñëîÿ êîíòðîëëåðà âåá-ïðèëîæåíèÿ íà îñíîâå àðõèòåêòóðû REST 6

Page 7: Контроллер Web-приложения на основе REST

Университет Текарт

Êîä îïèñàíèÿ ñòðóêòóðû ïðèëîæåíèÿ

static public function main() {

WS::Runner()->run(

WS_DSL::status(array(404 => 'http/not-found', 500),

WS_DSL::environment(array('urls' => App_URL::mapper()),

WS_DSL::config('../etc/p2.php',

WS_DSL::cache(array( /* caching parameters */ ),

WS_DSL::orm(P2::db(),

WS_DSL::session(

WS_DSL::auth_session(App::db(),

WS_DSL::application_dispatcher(array(

'/' => 'App.Front.Application',

// ...

'news' => 'App.News.Application'),

'App.WS.Pages.Application' )))))))));

}

Ïîñòðîåíèå ñëîÿ êîíòðîëëåðà âåá-ïðèëîæåíèÿ íà îñíîâå àðõèòåêòóðû REST 7

Page 8: Контроллер Web-приложения на основе REST

Университет Текарт

JAX RS � îñíîâà ðåàëèçàöèè REST-ñåðâèñîâ

Ïî÷åìó ìû âûáðàëè JAX RS?

Ïðîñòîé ñòàíäàðò;

Ïðîçðà÷íî ïåðåíîñèò ìîäåëü REST íà óðîâåíü êîäà;

Óäîáíàÿ ðàáîòà ñ âëîæåííûìè ðåñóðñàìè;

Íå íàêëàäûâàåò îãðàíè÷åíèé íà êëàññû ðåñóðñîâ.

Íàøå ðåøåíèå íà ïðèíöèïàõ JAX RS:

Ñîáñòâåííûé DSL îïèñàíèÿ ðåñóðñîâ âìåñòî àííîòàöèé;

Îòêàç îò ïðîèçâîëüíîãî ïîðÿäêà îïðåäåëåíèÿ ðåñóðñîâ äëÿóïðîùåíèÿ àëãîðèòìà;

Íåêîòîðûå âîçìîæíîñòè îòñóòñòâóþò � ðåàëèçóåì ïîçæå.

Ïîñòðîåíèå ñëîÿ êîíòðîëëåðà âåá-ïðèëîæåíèÿ íà îñíîâå àðõèòåêòóðû REST 8

Page 9: Контроллер Web-приложения на основе REST

Университет Текарт

Îáúåêòû ðåñóðñîâ

Ðåñóðñ � ïðîñòî PHP îáúåêò;

Íå îáÿçàòåëüíî íàñëåäîâàòü îò ðîäèòåëüñêîãî êëàññà èëèðåàëèçîâûâàòü èíòåðôåéñ.

class App_Stories_Index {public function index() { ... }public function draft() { ... }public function create() { ... }public function story($id) { return App_Stories::Story($this->db->stories->find($id));

}

Íà ïðàêòèêå èìååò ñìûñë âûíîñèòü îáùóþôóíêöèîíàëüíîñòü â ðîäèòåëüñêèé êëàññ, íî ýòî íåòðåáîâàíèå ôðåéìâîðêà.

Ïîñòðîåíèå ñëîÿ êîíòðîëëåðà âåá-ïðèëîæåíèÿ íà îñíîâå àðõèòåêòóðû REST 9

Page 10: Контроллер Web-приложения на основе REST

Университет Текарт

Ìåòîäû êëàññà ðåñóðñà

Êëàññ ðåñóðñà ðåàëèçóåò íàáîð ìåòîäîâ:

âñïîìîãàòåëüíûå ìåòîäû äëÿ âíóòðåííåãî èñïîëüçîâàíèÿ;

HTTP-ìåòîäû: ìåòîäû îáðàáàòûâàþùèå ðàçëè÷íûå âèäûçàïðîñîâ;

ñóáëîêàòîðû: ìåòîäû, ïîðîæäàþùèå ýêçåìïëÿðû êëàññîââëîæåííûõ ðåñóðñîâ.

íà ïàðàìåòðû ìåòîäîâ íå íàêëàäûâàåòñÿ íèêàêèõîãðàíè÷åíèé.

çíà÷åíèÿ ïàðàìåòðîâ ïîäñòàâëÿþòñÿ àâòîìàòè÷åñêè èñõîäÿèç èìåíè ïàðàìåòðà.

Ïîñòðîåíèå ñëîÿ êîíòðîëëåðà âåá-ïðèëîæåíèÿ íà îñíîâå àðõèòåêòóðû REST 10

Page 11: Контроллер Web-приложения на основе REST

Университет Текарт

ßçûê îïèñàíèÿ ðåñóðñîâ

Äëÿ ïðèíÿòèÿ ðåøåíèÿ î âûçîâå ìåòîäà ðåñóðñàíåîáõîäèìî èìåòü ïîëíîå îïèñàíèå äîñòóïíûõ ðåñóðñîâ èèõ ìåòîäîâ;

Ðåàëüíî âûïîëíÿåòñÿ êîä îäíîãî èëè íåñêîëüêèõ ðåñóðñîâ,íåò íåîáõîäèìîñòè çàãðóæàòü âñå ðåñóðñû;

Îïèñàíèå ðåñóðñîâ, ñîñòàâëÿþùèõ ïðèëîæåíèå, äîëæíîáûòü îòäåëåíî îò êîäà ðåñóðñîâ;

Ñîçäàåì ñâîé DSL äëÿ îïèñàíèÿ ñòðóêòóðû ïðèëîæåíèÿ.

×àñòî ïðèëîæåíèå ìîæíî ðàçáèòü íà îòäåëüíûåíåçàâèñèìûå ïðèëîæåíèÿ � ìèíèìèçàöèÿ îáúåìà îïèñàíèÿäëÿ îòäåëüíîãî çàïðîñà.

PHP � íå ñàìûé óäîáíûé ÿçûê äëÿ íàïèñàíèÿ DSL, íî êîå-÷òî ñäåëàòü ìîæíî.

Ïîñòðîåíèå ñëîÿ êîíòðîëëåðà âåá-ïðèëîæåíèÿ íà îñíîâå àðõèòåêòóðû REST 11

Page 12: Контроллер Web-приложения на основе REST

Университет Текарт

Îïèñàíèå ðåñóðñîâ ïðèëîæåíèÿ

Ïðèìåð: íîâîñòíûå ñòàòüè è RSS-ëåíòû äëÿ íîâîñòåé,ïðèíàäëåæàùèõ ê ðàçëè÷íûì ðóáðèêàì.

WS_REST_DSL::Application($this)->media_type('rss', 'application/xhtml+xml')->begin_resource('category', 'P2.WS.News.Category', '{name:[a-zA-Z-]+/[a-zA-Z]+}')->

get_for('{page_no:\d+}', 'index')->get_for('', 'index_rss', 'rss')->get_for('top', 'top_rss', 'rss')->get_for('most-popular', 'most_popular_rss', 'rss')->index()->

end->begin_resource('story', 'P2.WS.News.Story', 'stories/{id:\d+}')->

get_for('{page_no:\d+}', 'index')->index()->

end->begin_resource('index', 'P2.WS.News.Index')->

get_for('most-popular', 'most_popular_rss', 'rss')->get_for('', 'index_rss', 'rss')->index('html')->

end->end;

Ïîñòðîåíèå ñëîÿ êîíòðîëëåðà âåá-ïðèëîæåíèÿ íà îñíîâå àðõèòåêòóðû REST 12

Page 13: Контроллер Web-приложения на основе REST

Университет Текарт

Îïèñàíèå ïðèëîæåíèÿ

resource($name, $classname, $path)

$name èìÿ ðåñóðñà;

$classname èìÿ êëàññà, ðåàëèçóþùåãî ðåñóðñ;

$path ïóòü ê ðåñóðñó â âèäå øàáëîíà URL.

begin_resource('category',

'P2.WS.News.Category',

'{name:[a-zA-Z-]+/[a-zA-Z]+}');

Ïîñòðîåíèå ñëîÿ êîíòðîëëåðà âåá-ïðèëîæåíèÿ íà îñíîâå àðõèòåêòóðû REST 13

Page 14: Контроллер Web-приложения на основе REST

Университет Текарт

Øàáëîíû URL

Ðåãóëÿðíûå âûðàæåíèÿ ñ èìåíîâàííûìè ïàðàìåòðàìè:

stories/{id:\d+}

archive/{year:\d\d\d\d}/{month:\d\d?}/{day:\d\d?}

Çíà÷åíèÿ ïàðàìåòðîâ àâòîìàòè÷åñêè ïîäñòàâëÿþòñÿ ïðèâûçîâå ìåòîäîâ.

public function story($id);

public function archive_daily($year, $month, $day);

Ïîñòðîåíèå ñëîÿ êîíòðîëëåðà âåá-ïðèëîæåíèÿ íà îñíîâå àðõèòåêòóðû REST 14

Page 15: Контроллер Web-приложения на основе REST

Университет Текарт

Îïèñàíèå ìåòîäîâ ðåñóðñà

Ìåòîä ðåñóðñà âûïîëíÿåò îáðàáîòêó çàïðîñîâ ðàçëè÷íîãî âèäàè ôîðìèðóåò îòêëèê.

method($name, $http_mask, $path, $formats = 'html');

$name èìÿ ìåòîäà;

$http_mask GET | POST | PUT | DELETE;

$path URL-øàáëîí äëÿ ìåòîäà;

$formats ñïèñîê ôîðìàòîâ, ïîääåðæèâàåìûõ ìåòîäîì.

Ïîñòðîåíèå ñëîÿ êîíòðîëëåðà âåá-ïðèëîæåíèÿ íà îñíîâå àðõèòåêòóðû REST 15

Page 16: Контроллер Web-приложения на основе REST

Университет Текарт

Ïàðàìåòðû âûçîâà ìåòîäîâ

Ìåòîä ìîæåò èìåòü ëþáîé íàáîð ïàðàìåòðîâ;

Åñëè èìÿ ïàðàìåòðà ñîâïàäàåò ñ èìåíåì ïàðàìåòðàøàáëîíà � ïîäñòàâëÿåòñÿ çíà÷åíèå ïàðàìåòðà;

Åñëè èìÿ ïàðàìåòðà âõîäèò â íàáîð ïðåäîïðåäåëåííûõèìåí � ïîäñòàâëÿåòñÿ ñîîòâåòñòâóþùåå çíà÷åíèå.

 ïðîòèâíîì ñëó÷àå ïîäñòàâëÿåòñÿ null.

Ïðåäîïðåäåëåííûå çíà÷åíèÿ:

env îêðóæåíèå (çàïðîñ + äàííûå, ñîçäàííûåïðåäûäóùèìè îáðàáîò÷èêàìè);

request http-çàïðîñ;

format ôîðìàò, äëÿ êîòîðîãî âûçâàí ìåòîä.

Ïîñòðîåíèå ñëîÿ êîíòðîëëåðà âåá-ïðèëîæåíèÿ íà îñíîâå àðõèòåêòóðû REST 16

Page 17: Контроллер Web-приложения на основе REST

Университет Текарт

Ôîðìàòû ïðåäñòàâëåíèé

Äëÿ êàæäîãî ìåòîäà ìîæíî óêàçàòü ñïèñîê ôîðìàòîâïðåäñòàâëåíèé.

Îïðåäåëåíèå ôîðìàòà � ïî ðàñøèðåíèþ çàïðàøèâàåìîãîäîêóìåíòà èëè HTTP-çàãîëîâêàì.

Íà êàæäûé ôîðìàò ìîæíî ïðåäóñìîòðåòü îòäåëüíûéìåòîä èëè îáðàáàòûâàòü âñå â îäíîì ìåòîäå, èñïîëüçóÿïàðàìåòð $format.

Ìîæíî îãðàíè÷èâàòü ôîðìàòû äëÿ öåëûõ ðåñóðñîâ.

get_for('most-popular', 'most_popular', 'html,rss');

Ïîñòðîåíèå ñëîÿ êîíòðîëëåðà âåá-ïðèëîæåíèÿ íà îñíîâå àðõèòåêòóðû REST 17

Page 18: Контроллер Web-приложения на основе REST

Университет Текарт

Ñóáëîêàòîðû

Ñîçäàíèå êëàññà, ñîîòâåòñòâóþùåãî âëîæåííîìó ðåñóðñó,ìîæåò áûòü âûïîëíåíî äèíàìè÷åñêè â ïðîöåññå îáðàáîòêè.

Ñóáëîêàòîð íå îáðàáàòûâàåò çàïðîñ;

Âìåñòî ýòîãî îí ïðèíèìàåò ðåøåíèå î ñîçäàíèèýêçåìïëÿðà êëàññà âëîæåííîãî ðåñóðñà;

Äëÿ ïîëó÷åííîãî ðåñóðñà çàíîâî âûïîëíÿåòñÿ ïðîöåññïîèñêà ìåòîäà îáðàáîòêè çàïðîñà.

sublocator($name, $path)

name èìÿ ìåòîäà-ñóáëîêàòîðà;

path øàáîí URL.

Ïîñòðîåíèå ñëîÿ êîíòðîëëåðà âåá-ïðèëîæåíèÿ íà îñíîâå àðõèòåêòóðû REST 18

Page 19: Контроллер Web-приложения на основе REST

Университет Текарт

Êàê âñå ýòî ðàáîòàåò

1 Îïðåäåëÿåì ôîðìàò (ðàñøèðåíèå èëè çàãîëîâîê);

2 Ïðîñìàòðèâàåì îïèñàíèÿ ðåñóðñîâ è ñîïîñòàâëÿåì ïóòü êàæäîãî ñ íà÷àëîì URL;

3 Åñëè íå íàøëè òàêîãî, ÷òî URL ñîîòâåòñòâóåò è ôîðìàò ïîääåðæèâàåòñÿ � îøèáêà;

4 Ðåñóðñ íàøëè, èùåì ìåòîä. Óáèðàåì èç URL ñîâïàâøóþ ñ ïóòåì ðåñóðñà ÷àñòü;

5 Ïðîñìîòðèâàåì âñå îïèñàíèÿ ìåòîäîâ ðåñóðñà, ñîïîñòàâëÿÿ øàáëîí ñ íà÷àëîì îñòàòêàURL;

6 Åñëè íåò íè http-ìåòîäà, íè ñóáëîêàòîðà, ïîäõîäÿùèõ ïî øàáëîíó URL, ôîðìàòó è ò.ä. �îøèáêà, ìåòîä íå ïîääåðæèâàåòñÿ.

7 Åñëè íàéäåí http-ìåòîä c ñîîòâåòñòâóþùèì øàáëîíîì URL, ôîðìàòîì è ìàñêîéHTTP-ìåòîäîâ � ñîçäàåì îáúåêòà êëàññà ðåñóðñà, ïîäñòàâëÿåì ïàðàìåòðû è âûçûâàåììåòîä. Ðåçóëüòàò ðàáîòû è åñòü ðåçóëüòàò âûïîëíåíèÿ. Ðàáîòà çàâåðøåíà.

8 Åñëè íàéäåí ñóáëîêàòîð ñ ñîîòâåòñòâóþùèì øàáëîíîì URL � ïîäñòàâëÿåì ïàðàìåòðû èâûçûâàåì ìåòîä.

9 Ðåçóëüòàò âûïîëíåíÿ ìåòîäà � íîâûé ðåñóðñ. Èùåì â ñïèñêå ðåñóðñîâ îïèñàíèå ðåñóðñàñîîòâåòñòâóþùåãî êëàññà.

10 Åñëè òàêîãî ðåñóðñà íåò � îøèáêà;

11 Óäàëÿåì ñîâïàâøóþ ñòðîêó èç íà÷àëà URL è âîçâðàùàåìñÿ â ïóíêò 4, è òàê äî òåõ ïîð,ïîêà íå íàéäåòñÿ http-ìåòîä.

Êîëè÷åñòâî ïðîõîäîâ îãðàíè÷åíî, /resource/ è /resource/index.html � ýêâèâàëåíòíû.

Ïîñòðîåíèå ñëîÿ êîíòðîëëåðà âåá-ïðèëîæåíèÿ íà îñíîâå àðõèòåêòóðû REST 19

Page 20: Контроллер Web-приложения на основе REST

Университет Текарт

Èíòåãðàöèÿ ñ ñîáñòâåííûì ORM-ðåøåíèåì

WS.REST.ORM � ñòàíäàðòíûé ìîäóëü äëÿ ïîñòðîåíèÿrestful API íà áàçå ORM;

ïðèâÿçûâàåòñÿ ê íåêîòîðîìó ñòàíäàðòíîìó íàáîðó àäðåñîâ,íàïðèìåð api/*;

êîíòðîëü äîñòóïà íà óðîâíå ñëîÿ áèçíåñ-ëîãèêè;

î÷åíü ïðîñòàÿ ðåàëèçàöèÿ, âñå äâà âèäà ðåñóðñîâ � äëÿìàïïåðîâ è ñóùíîñòåé;

ðåàëèçàöèÿ íå çàâèñèò îò ñïåöèôèêè ñëîÿ áèçíåñ-ëîãèêè.

Áèçíåñ-ëîãèêà + ñòàíäàðòíûé REST API + Rich Client (Dojo) =áûñòðàÿ ðåàëèçàöèÿ ñëîæíûõ ïðèëîæåíèé.

Ïîñòðîåíèå ñëîÿ êîíòðîëëåðà âåá-ïðèëîæåíèÿ íà îñíîâå àðõèòåêòóðû REST 20

Page 21: Контроллер Web-приложения на основе REST

Университет Текарт

Èíòåãðàöèÿ ORM-ðåøåíèåì � ïðîäîëæåíèå

$db->news->stories->most_popular->select()

GET /api/news/stories/most_popular/

$db->news->stories->insert($story);

POST /api/news/stories/

$story = $db->news->stories[15];

$db->news->stories->update($story);

$db->news->stories->delete($story);

PUT /api/news/stories/15/

DELETE /api/news/stories/15/

$db->news->categories[5]->stories;GET /api/news/categories/5/stories/

Ïîñòðîåíèå ñëîÿ êîíòðîëëåðà âåá-ïðèëîæåíèÿ íà îñíîâå àðõèòåêòóðû REST 21

Page 22: Контроллер Web-приложения на основе REST

Университет Текарт

×òî ìû âûèãðûâàåì îò èñïîëüçîâàíèÿ REST-ìîäåëè

óíèâåðñàëüíîñòü: êëàññè÷åñêèå âåá-ïðèëîæåíèÿ,âåá-ñåðâèñû, áýêåíä AJAX-ïðèëîæåíèé;

îäíîðîäíàÿ ñòðóêòóðà êîäà êëàññîâ êîíòðîëëåðîâ;

ïðîñòàÿ ðàáîòà ñ âëîæåííûìè ðåñóðñàìè: ñòðàíè÷íûéêîíòåíò, êàòàëîãè òîâàðîâ è ò.ä.;

âîçìîæíîñòü èñïîëüçîâàíèÿ îòäåëüíûõ êëàññîâ ðåñóðñîâ ââèäå áèáëèîòå÷íûõ êîìïîíåíò;

ðàñøèðÿåìîñòü.

Ïîñòðîåíèå ñëîÿ êîíòðîëëåðà âåá-ïðèëîæåíèÿ íà îñíîâå àðõèòåêòóðû REST 22

Page 23: Контроллер Web-приложения на основе REST

Âîïðîñû?