构建web服务
参考官方教程go-zero安装
//安装goctl插件
go install github.com/zeromicro/go-zero/tools/goctl@latest
//加载go-zero依赖
go get -u github.com/zeromicro/go-zero@latest
zero构建一个http服务器,基于goctl命令创建:
goctl api new demo

在目录下生成一个web服务

在web目录下,etc是web服务的整体配置,一般包括项目名称,主机,端口等;internal是一个web的主体部分,包括路由,接口配置,逻辑部分,参数类型等;web.api是生成web服务的配置文件和grpc远程服务proto文件生成rpc服务器一样,web.api文件是生成控制器也叫接口的配置文件;web.go文件web服务的入口文件,服务器通过改文件启动。

在internal文件夹下,包含配置文件,控制器,逻辑部分,参数集等。需要加入自己的逻辑部分只需要修改logic目录下的文件即可。
根据官网的提示在logic.go文件27行添加如下代码:

resp = new(types.Response)
resp.Message = req.Name
切换到web目录下,运行web程序

浏览器输入http://127.0.0.1:8888/from/me

上述步骤实现了基于go-zero的web服务,这个web是基于go的net/http重构的,可能go较为流行的gin框架,go-zero的实现的web和gin还是有很大的区别的。
config.go文件
用来记载etc文件的yml的配置,具体配置项如下:

svc目录
该目录的文件将config的配置加载到控制器中。
handler目录
控制器负责转发路由,在routes.go中就是路由:
func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
server.AddRoutes(
[]rest.Route{
{
Method: http.MethodGet,
Path: "/from/:name",
Handler: WebHandler(serverCtx),
},
},
)
}
zero的路由不用与gin,其是通过路由注册的方式。在zero中rest是zero的web对象,rest.RestConf是配置类。

rest.Server是web容器,包含引擎和路由,提供了众多方法配置路由和引擎。

rest.Route是一个整体的路由对象,包含请求方法,请求路径和处理逻辑。

AddRoutes是rest.Server提供的注册路由的方法,其参数是路由对象数组[]rest.Route。

如上的注册逻辑,路由地址和方法以及处理逻辑均被注册到web容器中。
//路由对象也可分离出来
var routeList []rest.Route = []rest.Route{
//rest.Route
//...
}
路由的处理函数还有一个参数,来自svc目录,该结构体封装了rest.RestConf也就是web容器的配置类。

转到路由处理函数,该配置类直到调用逻辑部分才被调用,如下图:

svc.ServiceContext就是封装了一下config结构体,logx.Logger是日志,context.Context是上下文连接,这个才是最重要的,就像gin的gin.Context一样。

这些并不需要开发者完全使用,结构体的多层封装是为了方便扩展,如果需求不高,直接使用默认的即可。
因此,这个封装的
svc.ServiceContext的配置参数并不是必须的。存在这个参数可以改变对上下文,日志更改,不存在就是使用框架默认的。
那么一个处理函数必须包含那些必要的条件呢?接下来从一个函数来解析。

看到goctl生成的标准路由处理函数,之前已经说明了不需要svc.ServiceContext参数,那么http.HandlerFunc返回值函数就是必须的了。

看到http.HandlerFunc的源码其本身是一个函数类型,且携带了两个参数,一个响应一个请求。
那么就可以得到结论,路由处理函数是返回类型为http.HandlerFunc的任意函数。
只要自定义的函数满足上述条件,就可以当做路由处理函数注册到路由的rest.Route对象。
// 自定义处理函数
func MyHandler() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
httpx.OkJsonCtx(r.Context(), w, "hello")
}
}
//路由注册
func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
server.AddRoutes(
[]rest.Route{
{
Method: http.MethodGet,
Path: "/from/:name",
Handler: WebHandler(serverCtx),
},
{
Method: http.MethodGet,
Path: "/hello",
Handler: MyHandler(),
},
},
)
}
启动web服务器,在浏览器端访问


另外,如下图所示查看处理函数的参数,响应参数和请求参数。

显然对于http的请求与响应操作。但是官方使用了httpx这个库,转到该库可以看到内部函数大多都包含http.ResponseWriter对其进一步封装。

开发者可以使用http.ResponseWriter元素返回参数,也可以使用httpx提供的方法返回数据。后者的优势是可以直接返回结构体不用在序列化操作。
// 返回短文
func ArticleController() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
//定义结构体
type Article struct {
Str string
}
art := Article{
"开发者可以使用http.ResponseWriter元素返回参数,也可以使用httpx提供的方法返回数据。后者的优势是可以直接返回结构体不用在序列化操作。",
}
httpx.OkJson(w, art)
}
}
路由处理函数可以模块化并自己封装,实现定制的服务。
最后就是api文件了,api文件是goctl插件一键化生成一个控制的配置文件,通过api的一些简单的配置可以直接生成一个控制,开发者只需要编写逻辑部分,非常方便。

有兴趣的可以了解api语法,使用自动生成工具会快捷很多。



![[AJAX]使用fetch发送请求](https://img-blog.csdnimg.cn/15fbb08dc2b24c35a1a69af815cb71b9.png)















