GitHub地址 https://github.com/zhuxiujia/GoMybatisMall
首先让我们 对比 看看 Java是如何写接口(要支持swagger注解)
@Controller
@Api(
description = "验证码生成控制器"
)
public class CaptchaImageController {
private static Logger logger = LoggerFactory.getLogger(CaptchaImageController.class);
private static final String NO_CACHE = "No-cache";
@Resource
private SmsVerificationService smsVerificationService;
public CaptchaImageController() {
}
@RequestMapping({"/image/code/phone"})
@ApiOperation(
value = "得到一个校验码",
notes = "得到一个校验码",
httpMethod = "POST",
produces = "image/png"
)
public void getCode(@RequestParam("phone") String phone, HttpServletRequest request, HttpServletResponse response) throws ServiceException {
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "No-cache");
response.setDateHeader("Expires", 0L);
response.setContentType("image/jpeg");
if (phone != null && phone.length() == 11) {
try {
String code = ValidateCodeUtil.createVcode();
this.smsVerificationService.saveVerificationImageCode(phone, code);
ValidateCodeUtil.write(code, response);
logger.info("产生一个验证码[" + code + "],保存于 key[" + phone + "]");
} catch (Exception var6) {
logger.error("生成验证图片失败!", var6);
throw new ServiceException(var6);
}
} else {
throw new ServiceException(new Object[]{"手机号不正确!", phone});
}
}
}
再来看看go 这边写接口(要支持swagger注解)
type CaptchaApi struct {
easy_mvc.Controller `doc:"验证码API"`
StoreService *service.StoreService `inject:"StoreService"`
GetImage func(phone string, writer http.ResponseWriter) interface{} `path:"/api/captcha" arg:"phone,w" doc:"图形验证码接口" doc_arg:"phone:手机号,w:_"`
Slide func(phone string, writer http.ResponseWriter) interface{} `path:"/api/captcha/slide" arg:"phone,w" doc:"图形验证码接口" doc_arg:"phone:手机号,w:_"`
}
func (it *CaptchaApi) Routers() {
it.GetImage = func(phone string, writer http.ResponseWriter) interface{} {
if phone == "" {
return errors.New("手机号不能空!")
}
if len(phone) != 11 {
return errors.New("手机号不正确!")
}
//生成4位随机数字
var digs = captcha.RandomDigits(4)
var code = toDigitString(digs)
//save code
var err = it.StoreService.SaveImageCode(service.ImageCodeDTO{
Phone: phone,
Code: code,
})
if err != nil {
return err
}
var img = captcha.NewImage("", digs, 80, 42)
log.Println("产生一个验证码[" + code + "],保存于 key[" + phone + "]")
writer.Header().Set("Content-Type", "image/png")
img.WriteTo(writer)
return nil
}
it.Init(it)
app_context.Context.Provide(&inject.Object{
Value: it,
})
}
有木有感觉 go 写 貌似 更加的 便利和简洁~ 而且。。。。和spring 似曾相识,对。要的就是这种感觉~
再来看看具体的项目
基于GoMybatis的商城 微服务 项目
本项目使用基本的微服务设计(Controller-Service Discovery-Rpc LB-Service)拆分粒度为最大化(仅包含 一个网关和一个微服务,实际项目需要根据业务自己评估拆分)
关于网关(自行设计controller 作为网关做鉴权,注意本项目作为案例未加入,但是可以把controller层视为网关)
关于链路追踪(需要自行封装链路追踪,本项目基于rpc ,使用方式上没差别。注意本项目未加入)
关于熔断(需要自行封装熔断,本项目基于rpc ,使用方式上没差别。注意本项目未加入)
关于分布式唯一id(推荐使用其他的算法例如 雪花snowflake,本项目为了简单 默认使用uuid生成)
关于服务发现(本项目使用consul,也意味着支持spring cloud 调用基于本项目的集群)
关于sql不推荐或极少使用join语句,外键,触发器,存储过程(一般不超过3条,且join的应该是同业务的表,禁止跨服务join),而是使用 查询后组合的方法(因为go查询并发执行,为分库分表做万全准备)
gomybatis的xml里不出现任何的包名(得益于 设计之初 遵循单一职责原则和序列化方法定义在xml中和结构体tag中)似乎有点洁癖+强迫症,哈哈
关于事务,已处理好core服务中嵌套事务传播行为
秒启动(完成项目扫描,bean注入,总耗时小于1秒内)
支持 Swagger UI(go语言中唯一使用接口注解)和移动端前端沟通更便利~
安装依赖,win/mac os 命令行执行(前提,需要安装go环境,并且建议打开go mod 选项为auto,自行百度教程~)
go mod download
2020/04/06 02:32:34 [easy_mvc] swagger ui yaml config on :http://127.0.0.1:8000/doc 2020/04/06 02:32:34 [easy_mvc] swagger ui web start on :http://127.0.0.1:8000/swagger
{"code":-1,"msg":"手机号不能空!","data":null}
GitHub地址 https://github.com/zhuxiujia/GoMybatisMall