摘要

在之前的几篇文章中,我们从如何实现最简单的HTTP服务器,到如何对路由进行改进,到如何增加中间件。总的来讲,我们已经把Web服务器相关的内容大概梳理了一遍了。在这一篇文章中,我们将从最简单的一个main函数开始,慢慢重构,来研究如何把API设计的更加规范和具有扩展性。

1 构建一个Web应用

gin
MySQLRedis

这是一个简单到不能再简单的登录接口了。请求之后的返回的结果如下:

HandlerPOSTbody

然后应该在数据库中进行比对,在这里省略了这一步骤

我们创建了一个结构体,作为返回的JSON结构

gin
Content-Typeapplication/json
main

好,下面我们开始重构

2 Handler

mainHandler
main

是不是感觉已经好很多了。

mainHandler
Handler


在这里我们发现这个包的代码还是不够整洁

为什么呢,因为我们把返回结果也放到了这个包中。而返回结果,他应该是通用的。

既然是通用的,那我们就应该把它抽象出来。

3 Response

我们来看看此时包的结构:

common

来看看我们抽象出的response:

简单来讲,就是设置了请求成功请求错误的返回结果。在请求成功的返回结果中,有不返回数据的空结果以及返回了一些查询数据的结果。在失败的结果中,有默认的结果,和带具体信息的结果。

这些需要按照实际的情况来处理,这里只是做个示范。

successtruecode0successfalsecodesuccessResponsefailResponse函数
ginJSONresponse


如图:

其余的任何函数,在外部都是无法调用的。

此时,我们再来看看Handler


此时,无论在哪个Handler中,我们只需要调用http://response.Xxx,就能返回数据了。

到了这里,Handler部分基本上讲完了。但是作者在这里还没有实现对错误结果的抽象,你可以自己试试看。

4 服务启动

现在我们的main函数虽然比起之前简洁了不少:


但是,看起来整洁只是因为这里只有一个路由。

main
run.go
run.gomain
main


真的是越来越像Spring boot了(笑)

这样子的话,我们的应用入口就显得很简洁了。但是在Run函数中,依旧没有解决我们说的当路由增加之后的复杂性,我们继续往下重构。

5 Router

Run()

所以,我们应该把路由部分的服务抽象出来。

我们之间来看看效果:

Run()
initial.Router()
applicationinitialinitialrun.go
router.go

很容易理解,在这个Router()方法中,定义了中间件,路由分组这些东西。

这里先解释一下:

我们先设置了一个空的路由分组,这个分组是作为根分组存在的。然后,我们把各个模块作为这个分组的子分组。举个例子:我们的项目中,有用户相关的模块,有订单相关的模块,那么这里的一个模块,就是一个分组,一个分组下面,有多个接口。


所以,我们就可以组成这些路由:

  • /manageUser/register
  • /manageUser/login
  • /order/add
  • /order/delete

所以,我们增加这样的目录:


router
apirouter.InitMangerUserRouter(api)/manageUser/*router
manageUsermanageUser
loginmanageUser

6 整体文件结构

  • api目录:所有的Handler
  • application目录:应用所需的各种服务,如路由,持久化,缓存等等,然后由run.go统一启动
  • common目录:公共资源,如抽象的返回结果等
  • router目录:注册各种路由分组
  • main.go:启动应用

7 写在最后

首先,谢谢你能看到这里~

在这一篇的文章中,我主要是总结了前面三篇文章的内容,构建了一个Web应用的Demo。这里面很多都是我自己对于Web应用结构的理解,不一定对,也不一定合适,主要是做一个示范,希望能够对你的学习起到一些启发启发作用。也希望你可以指出我的错误,我们一起进步~

到了这里,《Golang Web入门》系列就结束了,谢谢你们的支持。之前你们的关注和点赞,都是对我特别大的鼓励。也非常感谢你们在发现了错误之后的留言,让我知道了自己理解有误的地方。(鞠躬~

PS:如果有其他的问题,也可以在公众号找到作者。并且,所有文章第一时间会在公众号更新,欢迎来找作者玩~