一种多屏时代的通用 web 应用架构

35
种种种种种种种种 web 种种种种 种种种 @ 种种种种种种种 2013-5-19

Upload: -

Post on 19-May-2015

2.727 views

Category:

Technology


0 download

DESCRIPTION

2013-5-19 珠三角技术沙龙分享主题。

TRANSCRIPT

Page 1: 一种多屏时代的通用 web 应用架构

一种多屏时代的通用 web 应用架构

赖勇浩 @ 珠三角技术沙龙2013-5-19

Page 2: 一种多屏时代的通用 web 应用架构

自我介绍

● game → webgame → web● 珠三角技术沙龙组委、发起人之一● PyCon China 2011/2012 讲师

– Python 于 webgame 的应用– 页游开发中的 Python 组件与模式

● http://laiyonghao.com/

Page 3: 一种多屏时代的通用 web 应用架构

内容概述

● Web 架构的变迁● 实践经验分享● 未来之路

Page 4: 一种多屏时代的通用 web 应用架构

Web 架构的变迁( 1 )

browser server

text/html

Page 5: 一种多屏时代的通用 web 应用架构

多屏时代有点不同。

Page 6: 一种多屏时代的通用 web 应用架构

Web 架构的变迁( 2 )

browser

serverwap browser

app

Page 7: 一种多屏时代的通用 web 应用架构

Web 架构的变迁( 2 )

● 问题:– 返回什么?

Page 8: 一种多屏时代的通用 web 应用架构

Web 架构的变迁( 2 )

● def request_wants_json():● best = request.accept_mimetypes \● .best_match(['application/json', 'text/html'])● return best == 'application/json' and \● request.accept_mimetypes[best] > \● request.accept_mimetypes['text/html']

Page 9: 一种多屏时代的通用 web 应用架构

Web 架构的变迁( 2 )

● @app.route('/')● def show_items():● items = get_items_from_database()● if request_wants_json():● return jsonify(items=[x.to_json() for x in items])● return render_template('show_items.html',

items=items)

Page 10: 一种多屏时代的通用 web 应用架构

插播: Accept

Page 11: 一种多屏时代的通用 web 应用架构

插播: mimerender

● mimerender = mimerender.FlaskMimeRender()

● render_xml = lambda message: '<message>%s</message>'%message

● render_json = lambda **args: json.dumps(args)● render_html = lambda message:

'<html><body>%s</body></html>'%message● render_txt = lambda message: message

Page 12: 一种多屏时代的通用 web 应用架构

插播: mimerender

● @app.route('/')

● @app.route('/<name>')

● @mimerender(

● default = 'html',

● html = render_html,

● xml = render_xml,

● json = render_json,

● txt = render_txt

● )

● def greet(name='world'):● return {'message':

'Hello, ' + name + '!'}

● if __name__ == "__main__":

● app.run(port=8080)

Page 13: 一种多屏时代的通用 web 应用架构

插播: mimerender

● How to get it

– mimerender is in PyPI, so it's as easy as doing:– $ pip install mimerender

Page 14: 一种多屏时代的通用 web 应用架构

Web 架构的变迁( 2 )

browser

server

text/html

wap browser

app

text/vnd.wap.wml

application/json

Page 15: 一种多屏时代的通用 web 应用架构

Web 架构的变迁( 3 )

● 如果可以通过短信( SMS )使用业务……

Page 16: 一种多屏时代的通用 web 应用架构

Web 架构的变迁( 3 )

browser

adapter

text/html

wap browser

app

text/vnd.wap.wml

application/json

adapter

adapter

server

adapterSMS

application/json

Page 17: 一种多屏时代的通用 web 应用架构

Web 架构的变迁( 3 )

browser

adapter

text/html

wap browser

app

text/vnd.wap.wml

application/json

adapter

adapter

server

adapterSMS

application/json

Page 18: 一种多屏时代的通用 web 应用架构

Web 架构的变迁( 3 )

● 业务与展现分享– server 专注业务实现,只需要提供 http api ,无须理会数

据展现形式;– adapter 的业务简单,只需要维护会话,并对请求 / 响应进

行转换;● 易于分工

– 内部可以分小组– 甚至外包(解决了我团队不熟悉短信中心协议的问题)

● 易于扩展– 支持更多设备(如自助终端、语音电话)

Page 19: 一种多屏时代的通用 web 应用架构

Web 架构的变迁( 3 )

● 安全:对数据进行签名– client-id 、 client-key– sha1 – 让 Date header 必填来确保每次请救不同

Page 20: 一种多屏时代的通用 web 应用架构

实践经验分享

● Flask-RESTful

– https://github.com/twilio/flask-restful

Page 21: 一种多屏时代的通用 web 应用架构

Flask-RESTful: Argument Parsing

● parser = reqparse.RequestParser()● parser.add_argument('rate', type=int, help='Rate to

charge for this resource')● args = parser.parse_args()

● 支持必填项、多值项、重命名● 可从 post body 、 query

string 、 headers 、 cookies 、 file uploads 中读取

Page 22: 一种多屏时代的通用 web 应用架构

Flask-RESTful: Output Fields

● resource_fields = {● 'name': fields.String,● 'address': fields.String,● 'date_updated': fields.DateTime,● }● class Todo(Resource):● @marshal_with(resource_fields)● def get(self, **kwargs):● return db_get_todo() # Some function that queries the db

Page 23: 一种多屏时代的通用 web 应用架构

Flask-RESTful: Output Fields

● Renaming Attributes● Default Values● Custom Fields & Multiple Values● Url Field● Complex Structures● List Field● Nested Field

Page 24: 一种多屏时代的通用 web 应用架构

Flask-RESTful: Resource Method Decorators

● def authenticate(func):● @wraps(func)● def wrapper(*args, **kwargs):● ...● class Resource(restful.Resource):● method_decorators = [authenticate] # applies to all

inherited resources

Page 25: 一种多屏时代的通用 web 应用架构

测试

● 一般情况下使用 curl 足矣– $ curl http://localhost:5000/todos/todo3– {"task": "profit!"}

Page 26: 一种多屏时代的通用 web 应用架构

chtest

● $ chtest --help● usage: chtest [-h] [--config-file CONFIG_FILE] --path

PATH [--method METHOD]● [--arg ARG] [--header HEADER] [--ensure-status

ENSURE_STATUS]● [--ensure-header ENSURE_HEADER]● [--ensure-content ENSURE_CONTENT] [--print-

header PRINT_HEADER]● [--print-json-path PRINT_JSON_PATH]

Page 27: 一种多屏时代的通用 web 应用架构

requests

● chtest is requests powered● Requests: HTTP for Humans

– >>> r = requests.get('https://api.github.com/user', auth=('user', 'pass'))– >>> r.status_code– 200– >>> r.headers['content-type']– 'application/json; charset=utf8'– >>> r.text– u'{"type":"User"...'– >>> r.json()– {u'private_gists': 419, u'total_private_repos': 77, ...}

Page 28: 一种多屏时代的通用 web 应用架构

未来之路

● http-based VS tcp-based● Behavior-Driven Development

Page 29: 一种多屏时代的通用 web 应用架构

Web 架构的变迁( 3 )

browser

adapter

text/html

wap browser

app

text/vnd.wap.wml

application/json

adapter

adapter

server

adapterSMS

RPC ??

Page 30: 一种多屏时代的通用 web 应用架构

RPC 优劣

● 优势– 减少连接数– 更小的数据包– 乱序返回– 握手后的数据不需要签名( SSL/TLS )

● 劣势– 不能利用 HTTP 的基础设施– 需要学习好多新东西

Page 31: 一种多屏时代的通用 web 应用架构

lettuce.it

● Feature: Manipulate strings

● In order to have some fun

● As a programming beginner

● I want to manipulate strings

● Scenario: Uppercased strings

● Given I have the string "lettuce leaves"

● When I put it in upper case

● Then I see the string is "LETTUCE LEAVES"

Page 32: 一种多屏时代的通用 web 应用架构

lettuce.it

● >>> @step('I have the string "(.*)"')● ... def have_the_string(step, string):● ... world.string = string● >>> @step('I put it in upper case')● ... def put_it_in_upper(step):● ... world.string = world.string.upper()● >>> @step('I see the string is "(.*)"')● ... def see_the_string_is(step, expected):● ... assert world.string == expected, \● ... "Got %s" % world.string

Page 33: 一种多屏时代的通用 web 应用架构

lettuce.it

● from lettuce import step● from nose.tools import assert_equals

● @step('some step with "(.*)"'):● def some_step(step, from):● assert_equals(from, 'expectation')

Page 34: 一种多屏时代的通用 web 应用架构

End.

Thanks.

@laiyonghao

Page 35: 一种多屏时代的通用 web 应用架构

额外赠送: flask-pypi-proxy

您值得拥有。