Server

业务逻辑处理
1 Uppercase 将字符转换成大写字母
2 Count 获取当前字符的长度值

  1. package service
  2. import (
  3. "errors"
  4. "strings"
  5. )
  6. type StringService interface {
  7. Uppercase(string) (string, error)
  8. Count(string) int
  9. }
  10. type StringServiceImpl struct{}
  11. func (StringServiceImpl) Uppercase(s string) (string, error) {
  12. if s == "" {
  13. return "", errors.New("empty string")
  14. }
  15. return strings.ToUpper(s), nil
  16. }
  17. func (StringServiceImpl) Count(s string) int {
  18. return len(s)
  19. }

Endpoints

业务代码的中间处理层,将request 请求传递给业务层,将业务层的返回结果传递给请求层

  1. package endpoints
  2. import (
  3. "context"
  4. "github.com/baxiang/go-note/stringsvc-v1/service"
  5. "github.com/go-kit/kit/endpoint"
  6. )
  7. type UppercaseRequest struct {
  8. S string `json:"s"`
  9. }
  10. type uppercaseResponse struct {
  11. V string `json:"v"`
  12. }
  13. type CountRequest struct {
  14. S string `json:"s"`
  15. }
  16. type countResponse struct {
  17. V int `json:"v"`
  18. }
  19. type commonResponse struct {
  20. Message string `json:"message"`
  21. Code int `json:"code"`
  22. Data interface{} `json:"data"`
  23. }
  24. func MakeUppercaseEndpoint(svc service.StringService) endpoint.Endpoint {
  25. return func(_ context.Context, request interface{}) (response interface{}, err error) {
  26. req := request.(UppercaseRequest)
  27. v, err := svc.Uppercase(req.S)
  28. if err != nil {
  29. return commonResponse{Data: nil, Message: err.Error(), Code: 1000}, nil
  30. }
  31. return commonResponse{Data: uppercaseResponse{v}, Message: "success", Code: 0}, nil
  32. }
  33. }
  34. func MakeCountEndpoint(svc service.StringService) endpoint.Endpoint {
  35. return func(_ context.Context, request interface{}) (response interface{}, err error) {
  36. req := request.(CountRequest)
  37. v := svc.Count(req.S)
  38. return commonResponse{Data: countResponse{v}, Message: "", Code: 0}, nil
  39. }
  40. }

Transports

  1. package transport
  2. import (
  3. "context"
  4. "encoding/json"
  5. "github.com/baxiang/go-note/stringsvc-v1/endpoints"
  6. "net/http"
  7. )
  8. func DecodeUppercaseRequest(_ context.Context, r *http.Request) (interface{}, error) {
  9. var request endpoints.UppercaseRequest
  10. if err := json.NewDecoder(r.Body).Decode(&request); err != nil {
  11. return nil, err
  12. }
  13. return request, nil
  14. }
  15. func DecodeCountRequest(_ context.Context, r *http.Request) (interface{}, error) {
  16. var request endpoints.CountRequest
  17. if err := json.NewDecoder(r.Body).Decode(&request); err != nil {
  18. return nil, err
  19. }
  20. return request, nil
  21. }
  22. func EncodeResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
  23. return json.NewEncoder(w).Encode(response)
  24. }

main

  1. package main
  2. import (
  3. "github.com/baxiang/go-note/stringsvc-v1/endpoints"
  4. "github.com/baxiang/go-note/stringsvc-v1/service"
  5. transport "github.com/baxiang/go-note/stringsvc-v1/transports"
  6. kithttp "github.com/go-kit/kit/transport/http"
  7. "log"
  8. "net/http"
  9. )
  10. func main() {
  11. svc := service.StringServiceImpl{}
  12. uppercaseHandler := kithttp.NewServer(endpoints.MakeUppercaseEndpoint(svc), transport.DecodeUppercaseRequest, transport.EncodeResponse)
  13. countHandler := kithttp.NewServer(endpoints.MakeCountEndpoint(svc), transport.DecodeCountRequest, transport.EncodeResponse)
  14. http.Handle("/uppercase", uppercaseHandler)
  15. http.Handle("/count", countHandler)
  16. log.Fatal(http.ListenAndServe(":8090", nil))
  17. }

中间件开发

  1. package middleware
  2. import (
  3. "github.com/baxiang/go-note/stringsvc-v1/service"
  4. "github.com/go-kit/kit/log"
  5. "time"
  6. )
  7. type LoggingMiddleware struct {
  8. Logger log.Logger
  9. Next service.StringService
  10. }
  11. func (mw LoggingMiddleware)Uppercase(s string)(output string,err error){
  12. defer func(begin time.Time) {
  13. _ =mw.Logger.Log(
  14. "method", "uppercase",
  15. "input", s,
  16. "output", output,
  17. "err", err,
  18. "took", time.Since(begin),
  19. )
  20. }(time.Now())
  21. output, err = mw.Next.Uppercase(s)
  22. return
  23. }
  24. func (mw LoggingMiddleware) Count(s string) (n int) {
  25. defer func(begin time.Time) {
  26. _ = mw.Logger.Log(
  27. "method","count",
  28. "input",s,
  29. "output",n,
  30. "took",time.Since(begin),
  31. )
  32. }(time.Now())
  33. n = mw.Next.Count(s)
  34. return
  35. }

监控

  1. package middleware
  2. import (
  3. "github.com/baxiang/go-note/stringsvc-v1/service"
  4. "github.com/go-kit/kit/log"
  5. "time"
  6. )
  7. type LoggingMiddleware struct {
  8. Logger log.Logger
  9. Next service.StringService
  10. }
  11. func (mw LoggingMiddleware)Uppercase(s string)(output string,err error){
  12. defer func(begin time.Time) {
  13. _ =mw.Logger.Log(
  14. "method", "uppercase",
  15. "input", s,
  16. "output", output,
  17. "err", err,
  18. "took", time.Since(begin),
  19. )
  20. }(time.Now())
  21. output, err = mw.Next.Uppercase(s)
  22. return
  23. }
  24. func (mw LoggingMiddleware) Count(s string) (n int) {
  25. defer func(begin time.Time) {
  26. _ = mw.Logger.Log(
  27. "method","count",
  28. "input",s,
  29. "output",n,
  30. "took",time.Since(begin),
  31. )
  32. }(time.Now())
  33. n = mw.Next.Count(s)
  34. return
  35. }

main

  1. package main
  2. import (
  3. "github.com/baxiang/go-note/stringsvc-v1/endpoints"
  4. "github.com/baxiang/go-note/stringsvc-v1/middleware"
  5. "github.com/baxiang/go-note/stringsvc-v1/service"
  6. transport "github.com/baxiang/go-note/stringsvc-v1/transports"
  7. kithttp "github.com/go-kit/kit/transport/http"
  8. "github.com/go-kit/kit/log"
  9. "os"
  10. stdprometheus "github.com/prometheus/client_golang/prometheus"
  11. "github.com/prometheus/client_golang/prometheus/promhttp"
  12. kitprometheus "github.com/go-kit/kit/metrics/prometheus"
  13. "net/http"
  14. )
  15. func main() {
  16. logger := log.NewLogfmtLogger(os.Stderr)
  17. fieldKeys := []string{"method", "error"}
  18. requestCount := kitprometheus.NewCounterFrom(stdprometheus.CounterOpts{
  19. Namespace: "str",
  20. Subsystem: "string_service",
  21. Name: "request_count",
  22. Help: "Number of requests received.",
  23. }, fieldKeys)
  24. requestLatency := kitprometheus.NewSummaryFrom(stdprometheus.SummaryOpts{
  25. Namespace: "str",
  26. Subsystem: "string_service",
  27. Name: "request_latency_microseconds",
  28. Help: "Total duration of requests in microseconds.",
  29. }, fieldKeys)
  30. countResult := kitprometheus.NewSummaryFrom(stdprometheus.SummaryOpts{
  31. Namespace: "str",
  32. Subsystem: "string_service",
  33. Name: "count_result",
  34. Help: "The result of each count method.",
  35. }, []string{}) // no fields here
  36. var svc service.StringService
  37. svc = service.StringServiceImpl{}
  38. svc = middleware.LoggingMiddleware{logger, svc}
  39. svc = middleware.InstrumentingMiddleware{requestCount, requestLatency, countResult, svc}
  40. uppercaseHandler := kithttp.NewServer(endpoints.MakeUppercaseEndpoint(svc),
  41. transport.DecodeUppercaseRequest,
  42. transport.EncodeResponse)
  43. countHandler := kithttp.NewServer(endpoints.MakeCountEndpoint(svc),
  44. transport.DecodeCountRequest,
  45. transport.EncodeResponse)
  46. http.Handle("/uppercase", uppercaseHandler)
  47. http.Handle("/count", countHandler)
  48. http.Handle("/metrics", promhttp.Handler())
  49. logger.Log(http.ListenAndServe(":8080", nil))
  50. }

参考

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