基于Bottle 封装一下自用web前后端分离开发框架(1):项目规划

因起初开始自己入门web的时候,是由以前我们的大牛主管来引导,非常感谢他一直以来的指导。接下来的系列文章主要是自己再这几天使用了flask之后,尝试继续使用Bottle封装成类似的那种来处理。

关于代码说明

每一章节对应当前主题的代码来提供。

框架说明

  • Token令牌:使用JWT令牌机制,可用于单页面应用程序,合适做前后端分离等应用
  • bottle全局异常处理
  • 使用wtforms表单验证相关的表单提交参数
  • 重写HTTPError 统一异常返回格式,方便前端开发
  • 更详细log日志记录,记录整个请求链路相关记录,也可以记录自己定义记录
  • peewee orm数据库的使用和简单封装
  • 类似Flask蓝图应用

详细日志记录示例如下:

 2019-12-27 16:56:04:121 | process_id:40532 process_name:MainProcess | thread_id:24044 thread_name:MainThread | INFO |
{
    "headers":"{     "Content-Length": "0",     "Content-Type": "text/plain",     "Aaa": "sadasd",     "Sfdsdui": "sdasd",     "User-Agent": "PostmanRuntime/7.21.0",     "Accept": "*/*",     "Cache-Control": "no-cache",     "Postman-Token": "75287742-d0c9-429a-bdc5-f03072480e8d",     "Host": "127.0.0.1:8889",     "Accept-Encoding": "gzip, deflate",     "Connection": "keep-alive" }",
    "host":"127.0.0.1:8889",
    "ip":"127.0.0.1",
    "url":"[http://127.0.0.1:8889/?sdasd=43543&username=22222222222&AAAAAAAAAAAA=%E8%AF%B4%E7%9A%84%E5%B0%B1%E6%98%AF%E7%9A%84%E5%AF%8C%E5%AE%B6%E5%A4%A7%E5%AE%A4](http://127.0.0.1:8889/?sdasd=43543&username=22222222222&AAAAAAAAAAAA=%E8%AF%B4%E7%9A%84%E5%B0%B1%E6%98%AF%E7%9A%84%E5%AF%8C%E5%AE%B6%E5%A4%A7%E5%AE%A4)",
    "method":"POST",
    "params":{
        "query_string":"sdasd=43543&username=22222222222&AAAAAAAAAAAA=说的就是的富家大室",
        "query":{
            "sdasd":"43543",
            "username":"22222222222",
            "AAAAAAAAAAAA":"说的就是的富家大室"
        },
        "forms":""
    },
    "req_stime":"2019-12-27 16:56:03.773712",
    "req_links_logs":[
        {
            "link_index":1,
            "event_des":"请求开始"
        },
        {
            "link_index":2,
            "event_des":"第三方接口请求日志",
            "msg_dict":{
                "url":"[https://www.baidu.com](https://www.baidu.com/)",
                "method":"GET",
                "params":null,
                "params_str":"None",
                "this_time_out":"15s",
                "req_stime":"2019-12-27 16:56:03",
                "cost_time":58.509,
                "state_code":"200",
                "result":"<!DOCTYPE html> <!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta http-equiv=X-UA-Compatible content=IE=Edge><meta content=always name=referrer><link rel=stylesheet type=text/css href=https://ss1.bdstatic.com/5eN1bjq8AAUYm2zgoY3K/r/www/cache/bdorz/baidu.min.css><title>百度一下,你就知道</title></head> <body link=#0000cc> <div id=wrapper> <div id=head> <div class=head_wrapper> <div class=s_form> <div class=s_form_wrapper> <div id=lg> <img hidefocus=true src=//www.baidu.com/img/bd_logo1.png width=270 height=129> </div> <form id=form name=f action=//www.baidu.com/s class=fm> <input type=hidden name=bdorz_come value=1> <input type=hidden name=ie value=utf-8> <input type=hidden name=f value=8> <input type=hidden name=rsv_bp value=1> <input type=hidden name=rsv_idx value=1> <input type=hidden name=tn value=baidu><span class="bg s_ipt_wr"><input id=kw name=wd class=s_ipt value maxlength=255 autocomplete=off autofocus=autofocus></span><span class="bg s_btn_wr"><input type=submit id=su value=百度一下 class="bg s_btn" autofocus></span> </form> </div> </div> <div id=u1> <a href=http://news.baidu.com name=tj_trnews class=mnav>新闻</a> <a href=https://www.hao123.com name=tj_trhao123 class=mnav>hao123</a> <a href=http://map.baidu.com name=tj_trmap class=mnav>地图</a> <a href=http://v.baidu.com name=tj_trvideo class=mnav>视频</a> <a href=http://tieba.baidu.com name=tj_trtieba class=mnav>贴吧</a> <noscript> <a href=http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u=http%3A%2F%2Fwww.baidu.com%2f%3fbdorz_come%3d1 name=tj_login class=lb>登录</a> </noscript> <script>document.write('<a href="http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u='+ encodeURIComponent(window.location.href+ (window.location.search === "" ? "?" : "&")+ "bdorz_come=1")+ '" name="tj_login" class="lb">登录</a>');                 </script> <a href=//www.baidu.com/more/ name=tj_briicon class=bri style="display: block;">更多产品</a> </div> </div> </div> <div id=ftCon> <div id=ftConw> <p id=lh> <a href=http://home.baidu.com>关于百度</a> <a href=http://ir.baidu.com>About Baidu</a> </p> <p id=cp>©2017 Baidu <a href=http://www.baidu.com/duty/>使用百度前必读</a>  <a href=http://jianyi.baidu.com/ class=cp-feedback>意见反馈</a> 京ICP证030173号  <img src=//www.baidu.com/img/gs.gif> </p> </div> </div> </div> </body> </html> "
            },
            "remarks":"第三方接口请求【OK】"
        },
        {
            "link_index":3,
            "event_des":"第三方接口请求日志",
            "msg_dict":{
                "url":"[https://juejin.im/post/5dee431c518825122e0a764c](https://juejin.im/post/5dee431c518825122e0a764c)",
                "method":"POST",
                "params":{
                    "ssdsd":230
                },
                "params_str":"{'ssdsd': 230}",
                "this_time_out":"15s",
                "req_stime":"2019-12-27 16:56:04",
                "cost_time":179.218,
                "state_code":"404",
                "result":"<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>Error</title> </head> <body> <pre>Cannot POST /post/5dee431c518825122e0a764c</pre> </body> </html> "
            },
            "remarks":"第三方接口请求【FAIL】,status_code:404 错误"
        },
        {
            "link_index":4,
            "event_des":"第三方接口请求日志",
            "msg_dict":{
                "url":"[https://www.jianshu.com/p/c192f3dc3e0c](https://www.jianshu.com/p/c192f3dc3e0c)",
                "method":"POST",
                "params":{
                    "ssdsd":230
                },
                "params_str":"{'ssdsd': 230}",
                "this_time_out":"15s",
                "req_stime":"2019-12-27 16:56:04",
                "cost_time":96.011,
                "state_code":"403",
                "result":"<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html> <head><title>403 Forbidden</title></head> <body bgcolor="white"> <h1>403 Forbidden</h1> <p>You don't have permission to access the URL on this server. Sorry for the inconvenience.<br/> Please report this message and include the following information to us.<br/> Thank you very much!</p> <table> <tr> <td>URL:</td> <td>https://www.jianshu.com/p/c192f3dc3e0c</td> </tr> <tr> <td>Server:</td> <td>zurich</td> </tr> <tr> <td>Date:</td> <td>2019/12/27 16:56:04</td> </tr> </table> <hr/>Powered by Tengine</body> </html> "
            },
            "remarks":"第三方接口请求【FAIL】,status_code:403 错误"
        },
        {
            "link_index":5,
            "event_des":"请求结束"
        }
    ],
    "rsp_data":{
        "msg":"roleId 必须传入",
        "code":400,
        "error_code":10031
    },
    "cost_time":"353.0"
}

长远目标计划

基于Bottle做一个简单后台权限管理系统,自用
系统是基于https://github.com/wuyouzhuguli/FEBS-Vue的前端源码上来做,后端就改成了我自己用bottle

1.登入界面

image.png

2.系统主页

image.png

image.png

image.png

image.png

image.png

image.png

3.数据分析页

image.png

本文目标

  • 框架模块分层

准备环节

关于环境安装等问题,在此也不再重复的叙述,其实网上也有大把的教程。

项目规划

因为后续我们的很多的项目都依赖一个公共的基础库,而且相关的开发都是基于自由的基础库上进行开发,所以我个人的洗好,则是把相关的一些基础的放在同一个大项目文件夹下,这样也方便后续的其他微服务开发。

项目总体结构

1. 基础库划分

因为我个人的喜欢,还是喜欢把一些独立的东西放在独立的包下去管理。可能划分多也未必是好事,不过目前我基础库也不算是非常多,所有相关的包都是独立的。

image.png

相关的包的解析如下:

- lib 一些其他第三库源码包
- xcache 关于redis缓存工具包
- xcors 关于bottle跨域的处理包
- xexception 关于bottley全局异常捕获插件包
- xtyform 关于bottle表单验证处理包
- xwtforms 关于bottle使用WTForms表单验证处理包
- xhelper 关于常用一些工具类的封装
- xhttp 关于reuqests简单的封装,加上日志记录
- xlog 日志记录初始化基础吧包
- xmodels 关于peewee基础modeljw包
- xplugins 其他插件包的封装
- xresponse 关于响应报文统一封装包统一返回格式,方便前端开发
- xscheduler 任务调度基础
- xsingnal 信号库的简单封装,封装发送信号和接受信号的装饰器

2. API相关开发

因为每个项目都是独立的,所以后续各自项目开发人员都负责自己的项目即可。相关基础库原则上,只需要新增相关其他方法,后续同步上不及时的问题,也不会因为某个人修改了基础库,导致某个项目异常等问题。

项目划分明细

相关的包的解析如下:

- api 项目设计接口开发路由
- apirsp 统一定义返回响应体
- config 项目设计常量等信息配置(一般线上的话可能 会写入环境变量中)
- jobs  定义相关定时任务或消息队列任务
- log app产品的日志记录
- models 数据库下对于的ORM模型
- utils 针对此应用下一些特定的工具类
- validators 封装当前API接口使用到的表单校验器
- x-tests API单元测试
-- app 应用示例对象
-test-results.xml 测试结果
- test_start 加载x-tests下的测试用例,执行测试脚本

总结

因为个人喜欢问题,可能相关分包其实是有问题,过多的分包后期也许可能对管理来说可能会有点不好,不过,我个人喜欢的事一个独立的包处理独立的事,所以分包上,可能有点个人形式主义。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,236评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,867评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,715评论 0 340
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,899评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,895评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,733评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,085评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,722评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,025评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,696评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,816评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,447评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,057评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,254评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,204评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,561评论 2 343