跳转至

labstack/echo

通过 rk-boot,配合 rk-echo 插件,创建 labstack/echo 后台服务。

概述#

我们将会使用 rk-boot 启动 labstack/echo 微服务,并且添加 /v1/greeter API。

为了微服务的完整性,我们还会开启如下几个附加功能。

功能 介绍
Swagger UI 开启 Swagger UI
API Docs UI 开启 RapiDoc UI
Prometheus 客户端 开启 Prometheus 本地客户端
日志中间件 针对每个 API 请求,自动记录日志
Prometheus 中间件 针对每个 API 请求,自动记录 Prometheus 记录
原数据中间件 针对每个 API 请求,自动添加 RequestID 到 Header

安装#

go get github.com/rookie-ninja/rk-boot/v2
go get github.com/rookie-ninja/rk-echo

1. 创建 boot.yaml#

echo:
  - name: greeter
    port: 8080                    # 监听端口
    enabled: true                 # 开启微服务
    sw:
      enabled: true               # 开启 Swagger UI,默认路径为 /sw
    docs:
      enabled: true               # 开启 API Doc UI,默认路径为 /docs
    prom:
      enabled: true               # 开启 Prometheus 客户端,默认路径为 /metrics
    middleware:
      logging:
        enabled: true             # 开启 API 日志中间件
      prom:
        enabled: true             # 开启 API Prometheus 中间件
      meta:
        enabled: true             # 开启 API 原数据中间件,自动生成 RequestID

2. 创建 main.go#

为了能给 labstack/echo 提供 Swagger UI,我们需要在代码中添加一系列注视,然后通过 swag 命令行生成 swagger.json 文件。

package main

import (
  "context"
  _ "embed"
  "fmt"
  "github.com/labstack/echo/v4"
  "github.com/rookie-ninja/rk-boot/v2"
  "github.com/rookie-ninja/rk-echo/boot"
  "net/http"
)

// @title Swagger Example API
// @version 1.0
// @description This is a sample rk-demo server.
// @termsOfService http://swagger.io/terms/

// @securityDefinitions.basic BasicAuth

// @contact.name API Support
// @contact.url http://www.swagger.io/support
// @contact.email support@swagger.io

// @license.name Apache 2.0
// @license.url http://www.apache.org/licenses/LICENSE-2.0.html

func main() {
  // Create a new boot instance.
  boot := rkboot.NewBoot()

  // Register handler
  echoEntry := rkecho.GetEchoEntry("greeter")
  echoEntry.Echo.GET("/v1/greeter", Greeter)

  // Bootstrap
  boot.Bootstrap(context.TODO())

  boot.WaitForShutdownSig(context.TODO())
}

// Greeter handler
// @Summary Greeter service
// @Id 1
// @version 1.0
// @produce application/json
// @Param name query string true "Input name"
// @Success 200 {object} GreeterResponse
// @Router /v1/greeter [get]
func Greeter(ctx echo.Context) error {
  return ctx.JSON(http.StatusOK, &GreeterResponse{
    Message: fmt.Sprintf("Hello %s!", ctx.QueryParam("name")),
  })
}

type GreeterResponse struct {
  Message string
}

3.生成 swagger.json#

$ swag init

4.文件夹结构#

$ tree
.
├── boot.yaml
├── docs
│   ├── swagger.json
│   └── swagger.yaml
├── go.mod
├── go.sum
└── main.go

5.运行 main.go#

$ go run main.go
2022-04-14T16:53:20.148+0800    INFO    boot/echo_entry.go:668  Bootstrap EchoEntry     {"eventId": "f94b667c-edec-42b2-8d0f-c55b459dcf42", "entryName": "greeter", "entryType": "EchoEntry"}
2022-04-14T16:53:20.149+0800    INFO    boot/echo_entry.go:434  SwaggerEntry: http://localhost:8080/sw/
2022-04-14T16:53:20.149+0800    INFO    boot/echo_entry.go:437  DocsEntry: http://localhost:8080/docs/
2022-04-14T16:53:20.149+0800    INFO    boot/echo_entry.go:440  PromEntry: http://localhost:8080/metrics
------------------------------------------------------------------------
endTime=2022-04-14T16:53:20.149574+08:00
startTime=2022-04-14T16:53:20.148641+08:00
elapsedNano=933258
timezone=CST
ids={"eventId":"f94b667c-edec-42b2-8d0f-c55b459dcf42"}
app={"appName":"rk","appVersion":"local","entryName":"greeter","entryType":"EchoEntry"}
env={"arch":"amd64","domain":"*","hostname":"lark.local","localIP":"192.168.1.101","os":"darwin"}
payloads={"docsEnabled":true,"docsPath":"/docs/","echoPort":8080,"promEnabled":true,"promPath":"/metrics","promPort":8080,"swEnabled":true,"swPath":"/sw/"}
counters={}
pairs={}
timing={}
remoteAddr=localhost
operation=Bootstrap
resCode=OK
eventStatus=Ended
EOE

6.验证#

6.1 Swagger UI#

http://localhost:8080/sw/

6.2 API Docs UI#

我们使用了 RapiDocs 作为 API Docs UI。其实 RapiDocs 也可以替换 Swagger UI 测试 API,后续我们会考虑替换 Swagger UI。

http://localhost:8080/docs/

6.3 Prometheus 客户端#

http://localhost:8080/metrics

6.4 发送请求#

$ curl -vs "localhost:8080/v1/greeter?name=rk-dev"
* ...
< X-Request-Id: d95d3b00-0d10-4784-83bf-bf392cf8bd77
< X-Rk-App-Domain: *
< X-Rk-App-Name: rk
< X-Rk-App-Unix-Time: 2022-04-14T17:04:39.458193+08:00
< X-Rk-App-Version: local
< X-Rk-Received-Time: 2022-04-14T17:04:39.458193+08:00
< ...
{"Message":"Hello rk-dev!"}

6.5 验证 API 日志#

rk-boot 默认会使用如下格式打印 API 日志,也可以使用 JSON 格式,请参考用户指南。

------------------------------------------------------------------------
endTime=2022-04-14T17:04:39.458396+08:00
startTime=2022-04-14T17:04:39.458172+08:00
elapsedNano=223722
timezone=CST
ids={"eventId":"d95d3b00-0d10-4784-83bf-bf392cf8bd77","requestId":"d95d3b00-0d10-4784-83bf-bf392cf8bd77"}
app={"appName":"rk","appVersion":"local","entryName":"greeter","entryType":"EchoEntry"}
env={"arch":"amd64","domain":"*","hostname":"lark.local","localIP":"192.168.1.101","os":"darwin"}
payloads={"apiMethod":"GET","apiPath":"/v1/greeter","apiProtocol":"HTTP/1.1","apiQuery":"name=rk-dev","userAgent":"curl/7.64.1"}
counters={}
pairs={}
timing={}
remoteAddr=localhost:64006
operation=/v1/greeter
resCode=200
eventStatus=Ended
EOE

6.6 验证 Prometheus Metrics#

访问 http://localhost:8080/metrics

Cheers#