golang 和 c/c++ 比起来是一门新的语言, 一直想学, 网上搜集了一些资料, 有些人说很容易上手, 确实是这样, 和 C/C++ 比起来, 少了很多乱七八糟的语法. 学一门新的语言, 最好的方法就是动手写一些东西, 最近小程序也比较火, 也想学一下, 网络上搜索的一些开源项目, 基本上没有 golang 实现的, 大部分都是 Node.JS 和 java 写的, 那么我就来实现一个 golang 版的吧, 一石二鸟.
开发小程序前后端都需要开发, 自己的前端经验很少, 搜索了一些开源代码, 有一个小程序项目让人眼前一亮, Nideshop https://github.com/tumobi/nideshop , 界面做的不错, 代码结构也清晰, 而且前后端都实现了, 自己的目标是学习 golang 和小程序, 干脆用 golang 重写 nideshop 吧.
web 框架的选择
Node.JS 和 java 已经一些很成熟的框架了, 比如 Node.JS 的 thinkjs,java 的 spring 框架. golang 最近几年才火起来, 有一些 Web 框架也比较新, 有下面一些框架:
Beego: 开源的高性能 Go 语言 Web 框架.
- https://github.com/astaxie/beego
- https://beego.me
Buffalo: 使用 Go 语言快速构建 Web 应用.
- https://github.com/gobuffalo/buffalov
- https://gobuffalo.iov/
Echo: 简约的高性能 Go 语言 Web 框架.
- https://github.com/labstack/echo
- https://echo.labstack.com/
Gin:Go 语言编写的 Web 框架, 以更好的性能实现类似 Martini 框架的 API.
- https://github.com/gin-gonic/ginv
- https://gin-gonic.github.io/gin
Iris: 全宇宙最快的 Go 语言 Web 框架. 完备 MVC 支持, 未来尽在掌握.
- https://github.com/kataras/iris
- https://iris-go.com/
Revel:Go 语言的高效, 全栈 Web 框架.
- https://github.com/revel/revel
- https://revel.github.io/
Beego 是国人写的框架, 文档很全, 例子也不少, 用的人也多, 最后决定用这个框架.
使用 xorm 生成数据库 model
数据库采用的是 MySQL, 使用 golang 读写 MySQL beego 已经实现了 ORM 框架. 但是数据库表需要生成对应的 struct,beego 的 ORM 貌似没有自动生成的功能. 采用了一个开源库 https://github.com/go-xorm/cmd , 最后生成的数据库表像下面这样, 奇怪的是没有 JSON 标签, 而且这个 xorm 标签, 最后 golang 不认报了错. 还有一个问题是有些字段类型 xorm 生成错了. 比如, 数据库中的 DECIMAL 字段, xorm 生成的结构体中的字段类型为 string, 这个显然是错误的.
- type NideshopAd struct {
- AdPositionId int `xorm:"not null default 0 index SMALLINT(5)"`
- Content string `xorm:"not null default'' VARCHAR(255)"`
- Enabled int `xorm:"not null default 1 index TINYINT(3)"`
- EndTime int `xorm:"not null default 0 INT(11)"`
- Id int `xorm:"not null pk autoincr SMALLINT(5)"`
- ImageUrl string `xorm:"not null TEXT"`
- Link string `xorm:"not null default'' VARCHAR(255)"`
- MediaType int `xorm:"not null default 0 TINYINT(3)"`
- Name string `xorm:"not null default'' VARCHAR(60)"`
- }
moshopserver 框架结构
moshopserver 的框架结构很清晰也很简单.
前端小程序发起 HTTP 请求到 Router(router 转发请求的各个阶段能做一些过滤, 这个后面要说一下),router 识别出请求链接, 将其转发到相应的 controller 上面. 还有三个底层的 package:
models
单纯和数据库打交道的接口都放在这个 package 下面.
services
主要实现了三类功能, 和微信交互的接口, 快递查询接口和 token 生成, 检测接口.
Utils
一些基本的功能函数放在这个 package 下面.
Token 验证
token 的生成验证使用了 https://github.com/dgrijalva/jwt-go 这个第三方库, 使用这个库通过 token 来解析出 userID, 创建和验证 token 是否过期, 整个交互流程是下面这样子:
小程序打开的时候默认不登录, 调用后台接口, 因为没有 token, 解析不出来 userid, 返回小程序段提示用户登录.
小程序调用微信后台服务获取 userinfo, 调用 moshopserver 后台登录接口.
后台接口调用微信后台, 解密 userInfo 中的相关字段, 生成一条用户信息插入 moshopserver 数据库中. 然后从数据库中取出 userid, 生成带过期时间的 token. 返回给小程序.
小程序调用微信后台接口, 将 token 存储到微信服务端. 接下来每次调用 moshopserver 后台, 都要从微信后台取出 token, 然后传递到 moshopsever 后台.
如果 token 过期或者无效, 后端解析不出 userid, 返回给小程序, 让其再次登录. 生成新的 token. 如此反复.
Router 过滤器
Nideshop 中做了一些设计, 有些接口即使 token 过期也能访问, 不需要提示用户再次登录. moshopserver 中也实现了这个功能. 采用了 beego 中的过滤器:
beego.InsertFilter("/api/*", beego.BeforeExec, services.FilterFunc, true, true)
使用的是 BeforeExec 参数, 这个阶段 Router 已经识别出了 Controller 和 Action 的具体类型, 我们可以自己加判断, 到底哪些 Controller 和 Action 需要用户登录权限, 这些 Controller 和 action 放在了配置文件 API.conf 中:
- [controller]
- publicController= {
- 'index','catalog','topic','auth','goods','brand','search','region'
- }
- [action]
- publicAction={
- 'comment/list','comment/count','cart/index','cart/add','cart/checked','cart/update','cart/delete','cart/goodscount','pay/notify'
- }
如果 HTTP 请求链接的 Controller 和 Action 都不在配置文件中, 则跳过接口调用, 直接返回小程序提示其进行重新登录.
问题
moshopserver 还是有一些 bug, 因为测试不够充分, 应该也还存在一些未知的 bug, 以后慢慢修复.
已经问题:
订单列表中商品信息不显示.
用户登录后没有显示登录 (头像和用户名不显示)
欢迎 Star, 欢迎提问题.
https://github.com/harlanc/moshopserver
来源: https://www.cnblogs.com/harlanc/p/10995253.html