pdf
|<<
<
>
>>|
/
Nifty web apps on an OpenResty ---- {{#ci|Nifty}} web apps on an {{#x|OpenResty}} ☺{{#author|agentzh@gmail.com}}☺ {{#author|章亦春}} {{#date|2008.4}} ---- The {{#ci|history}} of the {{#x|web}}... + {{#cm|✓}} Web 1.0 ---- {{img src="images/web-1-0.png" width="695" height="620"}} ---- {{#v|Benefits}} {{#x|☺}} Server code is easy to write. {{#x|☺}} Browsers are easty to build as well. {{#x|☺}} Web 1.0 Spiders are happy. {{#v|Drawbacks}} {{#x|☺}} Pages {{#ci|refresh}} everytime the user takes an action. {{#x|☺}} Advanced spiders try very hard to extract data from HTML source. {{#x|☺}} Blog owner's server is {{#ci|fat}} and hard to scale ---- The {{#ci|history}} of the {{#x|web}}... {{#cm|✓}} Web 1.0 {{#cm|✓}} Web 2.0 ---- {{img src="images/web-2-0.png" width="648" height="660"}} ---- {{#v|Benefits}} {{#x|☺}} Data can be applied to view templates on client side. {{#x|☺}} Pages can be highly {{#ci|responsive}} via updaing just page regions. {{#v|Drawbacks}} {{#x|☹}} Server of the site owner is {{#ci|very fat}}, which is hard to deploy and hard to maintain. ---- The {{#ci|history}} of the {{#x|web}}... {{#cm|✓}} Web 1.0 {{#cm|✓}} Web 2.0 {{#cm|✓}} Post-mordern Web 2.0 ---- {{img src="images/post-web-2-0.png" width="885" height="586"}} ---- {{#v|Benefits}} {{#x|☺}} {{#ci|No}} database required on the site owner's server {{#x|☺}} Database has the full posibility to {{#ci|scale}} {{#v|Drawbacks}} {{#x|☹}} {{#ci|Two}} HTTP round-trips are required {{#x|☹}} Site owner's server is still {{#ci|fat}}. ---- The {{#ci|history}} of the {{#x|web}}... {{#cm|✓}} Web 1.0 {{#cm|✓}} Web 2.0 {{#cm|✓}} Post-mordern Web 2.0 {{#cm|✓}} Web X ---- {{img src="images/web-3-0.png" width="929" height="515"}} ---- {{#v|Benefits}} {{#x|☺}} {{#x|Clients}} access third-party service sites {{#ci|directly}}. {{#x|☺}} {{#x|Service}} is {{#ci|general}}, {{#ci|composible}}, and even {{#ci|recursive}}. {{#x|☺}} All the Web 2.0 {{#ci|goodies}}. {{#x|☺}} Site owner's server is {{#ci|extremely}} {{#x|thin}}. {{#x|☺}} {{#ci|Deployment}} of web sites is {{#x|trivial}}. {{#v|Drawbacks}} (which may be {{#ci|benefits}} at the same time) {{#x|☹}} Web {{#ci|1.0}} spiders {{#x|cannot}} find anything interesting at all in the HTML. {{#x|☹}} Web sites are too easy to {{#ci|steal}} and {{#x|re-distributed}} by others ---- {{#x|☺}} We have {{#ci|already}} produced such web sites belonging to the {{#x|Web X}} era! {{#tag|☆}} They're {{#ci|powered}} by the {{#x|OpenResty}} platform. {{#tag|☆}} They're written {{#ci|completely}} in {{#x|JavaScript}}. {{#tag|☆}} They consist of {{#ci|static}} files {{#x|only}}. ---- {{#x|☼}} My {{#ci|blog}} site {{http://blog.agentzh.org}} ---- {{img src="images/blog-agentzh.png" width="824" height="797"}} ---- {{#x|☼}} Yisou {{#ci|BBS}} {{http://www.yisou.com/opi/post.html}} ---- {{img src="images/yisou-bbs.png" width="939" height="757"}} ---- {{#x|☼}} OpenResty {{#ci|Admin}} site {{http://resty.eeeeworks.org/admin/}} ---- {{img src="images/admin-login.png" width="953" height="698"}} ---- {{img src="images/admin-index.png" width="964" height="757"}} ---- My blog site {{#x|=}} {{#kw|index.html}} {{#x|+}} {{#v|openresty.js}} {{#x|+}} {{#v|blog.js}} {{#x|+}} {{#v|jemplates.js}} {{#x|+}} {{#v|jquery.js}} {{#x|+}} {{#v|JSON.js}} {{#x|+}} {{#v|CSS/image}} ---- {{img src="images/blog_site.png" width="981" height="749"}} ---- Hey, my {{#ci|readers}} can write a {{#x|new}} blog site for my articles atop the {{#x|OpenResty}} API exposed by my \"{{#ci|agentzh}}\" account {{#ci|without}} my permission! ---- {{#cm| <!-- index.html --> }} <html> <head> <meta http-equiv=\"Content-Type\" content=\"text/html; charset={{#x|utf-8}}\" /> <script src=\"{{#x|JSON.js}}\"></script> <script src=\"{{#x|openresty.js}}\"></script> <script src=\"{{#x|blog.js}}\"></script> <title>My blog</title> </head> <body onload=\"{{#x|init()}}\"> <div id=\"{{#x|main}}\"></div> </body> </html> ---- {{#cm|// blog.js}} {{#kw|var}} openresty = null; {{#kw|function}} init () { openresty = {{#kw|new}} OpenResty.Client( { server: {{#x|'http://api.eeeeworks.org'}}, user: {{#x|'agentzh.Public'}} } ); openresty.callback = renderPosts; openresty.get( {{#x|'/=/model/Post/~/~'}}, { offset: 0, count: 10, order_by: 'id:desc' } ); } ---- {{#cm|// blog.js (continued)}} {{#kw|function}} renderPosts (res) { {{#kw|if}} (openresty.isSuccess(res)) { {{#kw|var}} html = ''; {{#kw|for}} ({{#kw|var}} i = 0; i < res.length; i++) { {{#kw|var}} post = res[i]; html += \"<h1>\" + post.title + \"</h1>\" + post.content + \"<p>Posted by \" + post.author + \"</p>\"; } document.getElementById(\"main\").innerHTML = html; } {{#kw|else}} { alert(\"Failed to fetch posts: \" + res.error); } } ---- {{#x|♡}} Hey, it {{#ci|runs}} now! + {{#v|$}} firefox {{#x|~/Desktop/sample/index.html}} ---- {{img src="images/sample-blog.png" width="861" height="675"}} ---- {{#ci|Concatenating}} HTML strings is {{#x|boring}} and no fun :( + ➥ Some {{#x|Jemplate}} love ---- {{#cm| <!-- post-list.tt --> }} {{#kw|[% FOREACH post = posts %]}} <h1>{{#kw|[% post.title %]}}</h1> {{#kw|[% post.content %]}} <p>Posted by {{#kw|[% post.author %]}}</p> {{#kw|[% END %]}} ---- {{#v|$}} {{#kw|jemplate}} --runtime > jemplates.js {{#v|$}} {{#kw|jemplate}} --compile {{#x|post-list.tt}} >> jemplates.js ---- {{#cm| <!-- index.html --> }} <html> <head> <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" /> <script src=\"JSON.js\"></script> <script src=\"openresty.js\"></script> <script src=\"blog.js\"></script> {{#x| <script src="jemplates.js"></script> }} <title>My blog</title> </head> <body onload=\"init()\"> <div id=\"main\"></div> </body> </html> ---- {{#cm|// blog.js (continued)}} {{#kw|function}} renderPosts (res) { {{#kw|if}} (openresty.isSuccess(res)) { {{#x|var html = Jemplate.process(}} {{#x|'post-list.tt', { posts: res } }} {{#x|);}} document.getElementById(\"main\").innerHTML = html; } {{#kw|else}} { alert(\"Failed to fetch posts: \" + res.error); } } ---- {{#x|♡}} Hey, it {{#ci|runs}} again! + {{#v|$}} firefox {{#x|~/Desktop/sample/index.html}} ---- So {{#x|what}} is {{#ci|OpenResty}} then? ---- {{#v|OpenResty}} is a {{#cm|✓}} {{#ci|general-purpose}} {{#x|RESTful}} web service platform {{#cm|✓}} REST {{#x|wrapper}} for {{#ci|relational}} databases {{#cm|✓}} Virtual web {{#ci|runtime}} for {{#x|RIA}} {{#cm|✓}} \"{{#ci|meta}} web site\" supporting {{#x|other sites}} via web services {{#cm|✓}} handy {{#ci|web database}} which can be accessed from {{#x|anywhere}} ---- {{#v|OpenResty}} is {{#ci|NOT}} a {{#cm|×}} {{#ci|server}}-side web application {{#x|framework}}. {{#cm|×}} relacement for highly scalable {{#ci|semi-structured}} data storage solutions like Amazon SimpleDB or CouchDB. ---- {{#v|OpenResty}} offers {{#cm|✓}} (scalable) {{#ci|relational}} data {{#x|storage}} {{#cm|✓}} {{#ci|truely}} {{#x|RESTy}} interface {{#cm|✓}} {{#ci|JSON/YAML}} data transfer format {{#cm|✓}} {{#x|SQL}}-based reusable {{#ci|views}} {{#cm|✓}} a REST-oriented {{#ci|role system}} for {{#x|ACL}} {{#cm|✓}} {{#ci|view}}-based {{#x|RSS feeds}} {{#cm|✓}} user-defined {{#ci|actions}} in {{#x|RestyScript}} {{#cm|✓}} native {{#ci|captchas}} {{#cm|✓}} {{#ci|cross-site}} {{#x|AJAX}} support ---- {{#x|♡}} The OpenResty {{#ci|FastCGI}} server is currently written in {{#x|Perl 5}}. ---- {{img src="images/resty-guts.png" width="768" height="574"}} ---- {{#x|♡}} The {{#x|PgFarm}} backend of OpenResty is designed to be {{#ci|scalable}}. ---- {{img src="images/cluster-arch.png" width="724" height="401"}} ---- \"{{#x|How}} can I get {{#ci|started}}?\" ➥ Write to {{#ci|agentzh@gmail.com}} to request an OpenResty {{#x|account}} ➥ OpenResty is on {{#ci|CPAN}} already! {{http://search.cpan.org/dist/OpenResty}} ---- \"{{#x|Where}} can I learn {{#ci|more}} about OpenResty?\" ➥ See the {{#x|OpenResty::Spec::Overview}} document {{http://search.cpan.org/perldoc?OpenResty::Spec::Overview}} ---- \"{{#ci|How}} can I get {{#x|involved}}?\" ➥ Write to {{#ci|agentzh@gmail.com}} to ask a commit bit! {{http://svn.openfoundry.org/openapi/trunk}} ---- {{#kw|☺}} {{#ci|Any questions}}? {{#kw|☺}}