Server
业务逻辑处理
1 Uppercase 将字符转换成大写字母
2 Count 获取当前字符的长度值
package service
import (
"errors"
"strings"
)
type StringService interface {
Uppercase(string) (string, error)
Count(string) int
}
type StringServiceImpl struct{}
func (StringServiceImpl) Uppercase(s string) (string, error) {
if s == "" {
return "", errors.New("empty string")
}
return strings.ToUpper(s), nil
}
func (StringServiceImpl) Count(s string) int {
return len(s)
}
Endpoints
业务代码的中间处理层,将request 请求传递给业务层,将业务层的返回结果传递给请求层
package endpoints
import (
"context"
"github.com/baxiang/go-note/stringsvc-v1/service"
"github.com/go-kit/kit/endpoint"
)
type UppercaseRequest struct {
S string `json:"s"`
}
type uppercaseResponse struct {
V string `json:"v"`
}
type CountRequest struct {
S string `json:"s"`
}
type countResponse struct {
V int `json:"v"`
}
type commonResponse struct {
Message string `json:"message"`
Code int `json:"code"`
Data interface{} `json:"data"`
}
func MakeUppercaseEndpoint(svc service.StringService) endpoint.Endpoint {
return func(_ context.Context, request interface{}) (response interface{}, err error) {
req := request.(UppercaseRequest)
v, err := svc.Uppercase(req.S)
if err != nil {
return commonResponse{Data: nil, Message: err.Error(), Code: 1000}, nil
}
return commonResponse{Data: uppercaseResponse{v}, Message: "success", Code: 0}, nil
}
}
func MakeCountEndpoint(svc service.StringService) endpoint.Endpoint {
return func(_ context.Context, request interface{}) (response interface{}, err error) {
req := request.(CountRequest)
v := svc.Count(req.S)
return commonResponse{Data: countResponse{v}, Message: "", Code: 0}, nil
}
}
Transports
package transport
import (
"context"
"encoding/json"
"github.com/baxiang/go-note/stringsvc-v1/endpoints"
"net/http"
)
func DecodeUppercaseRequest(_ context.Context, r *http.Request) (interface{}, error) {
var request endpoints.UppercaseRequest
if err := json.NewDecoder(r.Body).Decode(&request); err != nil {
return nil, err
}
return request, nil
}
func DecodeCountRequest(_ context.Context, r *http.Request) (interface{}, error) {
var request endpoints.CountRequest
if err := json.NewDecoder(r.Body).Decode(&request); err != nil {
return nil, err
}
return request, nil
}
func EncodeResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
return json.NewEncoder(w).Encode(response)
}
main
package main
import (
"github.com/baxiang/go-note/stringsvc-v1/endpoints"
"github.com/baxiang/go-note/stringsvc-v1/service"
transport "github.com/baxiang/go-note/stringsvc-v1/transports"
kithttp "github.com/go-kit/kit/transport/http"
"log"
"net/http"
)
func main() {
svc := service.StringServiceImpl{}
uppercaseHandler := kithttp.NewServer(endpoints.MakeUppercaseEndpoint(svc), transport.DecodeUppercaseRequest, transport.EncodeResponse)
countHandler := kithttp.NewServer(endpoints.MakeCountEndpoint(svc), transport.DecodeCountRequest, transport.EncodeResponse)
http.Handle("/uppercase", uppercaseHandler)
http.Handle("/count", countHandler)
log.Fatal(http.ListenAndServe(":8090", nil))
}
中间件开发
package middleware
import (
"github.com/baxiang/go-note/stringsvc-v1/service"
"github.com/go-kit/kit/log"
"time"
)
type LoggingMiddleware struct {
Logger log.Logger
Next service.StringService
}
func (mw LoggingMiddleware)Uppercase(s string)(output string,err error){
defer func(begin time.Time) {
_ =mw.Logger.Log(
"method", "uppercase",
"input", s,
"output", output,
"err", err,
"took", time.Since(begin),
)
}(time.Now())
output, err = mw.Next.Uppercase(s)
return
}
func (mw LoggingMiddleware) Count(s string) (n int) {
defer func(begin time.Time) {
_ = mw.Logger.Log(
"method","count",
"input",s,
"output",n,
"took",time.Since(begin),
)
}(time.Now())
n = mw.Next.Count(s)
return
}
监控
package middleware
import (
"github.com/baxiang/go-note/stringsvc-v1/service"
"github.com/go-kit/kit/log"
"time"
)
type LoggingMiddleware struct {
Logger log.Logger
Next service.StringService
}
func (mw LoggingMiddleware)Uppercase(s string)(output string,err error){
defer func(begin time.Time) {
_ =mw.Logger.Log(
"method", "uppercase",
"input", s,
"output", output,
"err", err,
"took", time.Since(begin),
)
}(time.Now())
output, err = mw.Next.Uppercase(s)
return
}
func (mw LoggingMiddleware) Count(s string) (n int) {
defer func(begin time.Time) {
_ = mw.Logger.Log(
"method","count",
"input",s,
"output",n,
"took",time.Since(begin),
)
}(time.Now())
n = mw.Next.Count(s)
return
}
main
package main
import (
"github.com/baxiang/go-note/stringsvc-v1/endpoints"
"github.com/baxiang/go-note/stringsvc-v1/middleware"
"github.com/baxiang/go-note/stringsvc-v1/service"
transport "github.com/baxiang/go-note/stringsvc-v1/transports"
kithttp "github.com/go-kit/kit/transport/http"
"github.com/go-kit/kit/log"
"os"
stdprometheus "github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
kitprometheus "github.com/go-kit/kit/metrics/prometheus"
"net/http"
)
func main() {
logger := log.NewLogfmtLogger(os.Stderr)
fieldKeys := []string{"method", "error"}
requestCount := kitprometheus.NewCounterFrom(stdprometheus.CounterOpts{
Namespace: "str",
Subsystem: "string_service",
Name: "request_count",
Help: "Number of requests received.",
}, fieldKeys)
requestLatency := kitprometheus.NewSummaryFrom(stdprometheus.SummaryOpts{
Namespace: "str",
Subsystem: "string_service",
Name: "request_latency_microseconds",
Help: "Total duration of requests in microseconds.",
}, fieldKeys)
countResult := kitprometheus.NewSummaryFrom(stdprometheus.SummaryOpts{
Namespace: "str",
Subsystem: "string_service",
Name: "count_result",
Help: "The result of each count method.",
}, []string{}) // no fields here
var svc service.StringService
svc = service.StringServiceImpl{}
svc = middleware.LoggingMiddleware{logger, svc}
svc = middleware.InstrumentingMiddleware{requestCount, requestLatency, countResult, svc}
uppercaseHandler := kithttp.NewServer(endpoints.MakeUppercaseEndpoint(svc),
transport.DecodeUppercaseRequest,
transport.EncodeResponse)
countHandler := kithttp.NewServer(endpoints.MakeCountEndpoint(svc),
transport.DecodeCountRequest,
transport.EncodeResponse)
http.Handle("/uppercase", uppercaseHandler)
http.Handle("/count", countHandler)
http.Handle("/metrics", promhttp.Handler())
logger.Log(http.ListenAndServe(":8080", nil))
}
参考
https://github.com/go-kit/kit/tree/master/examples
https://blog.csdn.net/wdy_yx/article/details/78389736?utm_medium=distribute.pc_relevant.none-task-blog-baidujs-1