1.05 Web框架概览-Echo框架分析

PART1. 基本使用

package echo

import (
	"github.com/labstack/echo/v4"
	"github.com/labstack/echo/v4/middleware"
	"net/http"
	"testing"
)

func TestHelloWorld(t *testing.T) {
	// Echo instance
	e := echo.New()

	// Middleware
	e.Use(middleware.Logger())
	e.Use(middleware.Recover())

	// Routes
	e.GET("/", hello)

	// Start server
	e.Logger.Fatal(e.Start(":8084"))
}

// Handle
func hello(c echo.Context) error {
	return c.String(http.StatusOK, "Hello, World!")
}

PART2. 结构体echo.Echo

从上述示例的e.Start(":8084")可以看出,echo.Echo结构体(即echo.New()的返回值)类似于Beego的HttpServer和GIN的Engine:

  • 注册路由:暴露了注册路由的方法,但echo.Echo本身并不是路由树的载体(echo.Echo只是组合了echo.Router)

  • 生命周期管理:如Echo.Start()/Echo.Shutdown()等方法

可以看到在该结构体中,有2个相似的字段:routerrouters:

  • router:表示路由树

  • routers:表示根据Host将路由树隔离,可以看做是类似namespace之类的概念,既是一种组织方式,也是一种隔离机制

一种观点认为:如果想要做一个类似namespace之类的隔离机制,应该使用一些更轻量级的方式.但如果仅仅是为了实现"根据Host将路由树隔离"的功能,不如创建2个Echo实例,而不是使用在1个Echo示例中使用一个map通过key来隔离.

PART3. Route和node

Router:表示路由树,而node表示的是路由树上的节点

3.1 Router

3.1.1 Route类型

实际上这里的Route类型才是真正表示1个路由的:

Router.tree字段表示一棵树的根节点,实际上该字段改名为root更加合适.

3.1.2 Router.echo

从上述echo.Echo结构体的定义中可以看到它有一个字段名为router,其类型为*Router;从Router结构体的定义中也能够看到它有一个字段名为echo,其类型为*Echo.很明显的双向引用.

这也是在有些情况下逼不得已的做法.比如GO原生的sql包中,sql.Tx里边维护了一个sql.DB的实例:

3.2 node

注意字段staticChildren(实际上children类型就是[]*node)、paramChildanyChild:

  • staticChildren:静态匹配

  • paramChild:参数路径

  • anyChild:通配符匹配

这种设计可以比较容易实现路由优先级和路由冲突检测

PART4. Context

Echo中的Context是一个大而全的接口,定义了处理请求和响应的各种方法.和Beego、Gin、Iris的Context没有什么区别.

硬要说区别的话,只是在Echo中这个抽象被定义为了一个接口而非结构体.这也就意味着可以为该接口提供不同的实现.当然其实没啥人给它提供不同的实现.

PART5. 核心抽象

核心抽象总结
  • Route & node:处理路由相关功能

  • Echo:类似Beego中的Beego的HttpServer和GIN中的Engine

  • Context:处理请求上下文

  • HandlerFunc:业务逻辑代码

PART6. 框架对比

Beego
GIN
Iris
Echo

代表服务器

HttpServer

Engine

Application

Echo

代表路由

ControllerRegister

methodTree

Route

Route

上下文

Context

Context

Context

Context

处理逻辑

HandlerFunc

HandlerFunc

HandlerFunc

HandlerFunc

所以实际上我们要造一个Web框架,就是要建立我们自己的这几个抽象.

PART7. WEB框架面试题

实际上,面整体Web框架的还是比较少的.大多数时候,面试都是聊具体的某个Web框架.且如果你打的是一些高端局,也不会问你怎么用,最多最多是问你怎么实现.

7.1 Web框架拿来做什么?

处理HTTP请求,为用户提供便捷API,为用户提供无侵入式的插件机制,提供如上传下载等默认功能.

7.2 为什么都已经有了http包,还要开发Web框架?

  • 高级路由功能

    • 参数匹配

    • 正则匹配

    • 通配符匹配

    • 这些功能shi 原生的net/http包不支持的

  • 封装HTTP上下文以提供简单API

  • 封装Server以提供生命周期控制

  • 设计插件机制以提供无侵入式解决方案

7.3 Web框架的核心?

  • 路由树

  • 上下文Context

  • Server

Last updated