go-kit三层架构

目录

    • go-kit三层架构
    • 三层架构代码
    • 第三方包配置路由
      • 实现RESTFUL风格
      • 代码改造
      • 实现多种方法

go-kit三层架构

go-kit三层架构_第1张图片

go-kit的架构如图分为三层结构:Transport层,Endpoint层,Service层。

Transport层主要负责与传输协议HTTP,GRPC,THRIFT等相关的逻辑;
Endpoint层主要负责request/response格式的转换,以及公用拦截器相关的逻辑;
Service层则专注于业务逻辑,就是我们的业务类、接口等相关信息存放。
go-kit除了经典的分层架构外,还在endpoint层提供了很多公用的拦截器,如log,metric,tracing,circuitbreaker,rate-limiter等,来保障业务系统的可用性。

go-kit三层架构_第2张图片

三层架构代码

go-kit三层架构_第3张图片

UserEndpoint.go:

package Services

import (
   "context"
   "github.com/go-kit/kit/endpoint"
)

type UserRequest struct {
   Uid int `json:"uid"`
}

type UserResponse struct {
   Result string `json:"result"`
}

func GenUserEndpoint(userService IUserService) endpoint.Endpoint {
   return func(ctx context.Context, request interface{}) (response interface{}, err error) {
      r := request.(UserRequest)
      result := userService.GetName(r.Uid)
      return UserResponse{Result: result}, nil
   }
}

UserService.go

package Services

type IUserService interface {
   GetName(userid int) string
}

type UserService struct {
}

func (this UserService) GetName(userid int) string {
   if userid == 101 {
      return "jiang"
   }
   return "tao"
}

UserTransport.go

package Services

import (
	"context"
	"encoding/json"
	"errors"
	"net/http"
	"strconv"
)

func DecodeUserRequest(c context.Context, r *http.Request) (interface{}, error) {
	if r.URL.Query().Get("uid") != "" {
		uid, _ := strconv.Atoi(r.URL.Query().Get("uid"))
		return UserRequest{
			Uid: uid,
		}, nil
	}
	return nil, errors.New("参数错误")
}

func EncodeUserResponse(ctx context.Context, w http.ResponseWriter, response interface{}) error {
    w.Header().Set("Content-type", "application/json")
	return json.NewEncoder(w).Encode(response)
}

main.go

package main

import (
   httptransport "github.com/go-kit/kit/transport/http"
   "go-kit/Services"
   "net/http"
)

func main() {
   user := Services.UserService{}
   endp := Services.GenUserEndpoint(user)

   serverHandler := httptransport.NewServer(endp, Services.DecodeUserRequest, Services.EncodeUserResponse)

   http.ListenAndServe(":8080", serverHandler)
}

go-kit三层架构_第4张图片

第三方包配置路由

实现RESTFUL风格

go get -u github.com/gorilla/mux

代码改造

main.go

package main

import (
   httptransport "github.com/go-kit/kit/transport/http"
   mymux "github.com/gorilla/mux"
   "go-kit/Services"
   "net/http"
)

func main() {
   user := Services.UserService{}
   endp := Services.GenUserEndpoint(user)

   serverHandler := httptransport.NewServer(endp, Services.DecodeUserRequest, Services.EncodeUserResponse)

   r := mymux.NewRouter()
   //r.Handle(`/user/{uid:\d+}`, serverHandler)
   r.Methods("GET").Path(`/user/{uid:\d+}`).Handler(serverHandler)

   http.ListenAndServe(":8080", r)
}

UserTransport.go

package Services

import (
   "context"
   "encoding/json"
   "errors"
   mymux "github.com/gorilla/mux"
   "net/http"
   "strconv"
)

func DecodeUserRequest(c context.Context, r *http.Request) (interface{}, error) {

   vars := mymux.Vars(r)

   if uid, ok := vars["uid"]; ok {
      uid, _ := strconv.Atoi(uid)
      return UserRequest{
         Uid: uid,
      }, nil
   }
   return nil, errors.New("参数错误")
}

func EncodeUserResponse(ctx context.Context, w http.ResponseWriter, response interface{}) error {
   w.Header().Set("Content-type", "application/json")
   return json.NewEncoder(w).Encode(response)
}

实现多种方法

main.go

package main

import (
   httptransport "github.com/go-kit/kit/transport/http"
   mymux "github.com/gorilla/mux"
   "go-kit/Services"
   "net/http"
)

func main() {
   user := Services.UserService{}
   endp := Services.GenUserEndpoint(user)

   serverHandler := httptransport.NewServer(endp, Services.DecodeUserRequest, Services.EncodeUserResponse)

   r := mymux.NewRouter()
   //r.Handle(`/user/{uid:\d+}`, serverHandler)
   r.Methods("GET", "DELETE").Path(`/user/{uid:\d+}`).Handler(serverHandler)

   http.ListenAndServe(":8080", r)
}

UserTransport.go

package Services

import (
   "context"
   "encoding/json"
   "errors"
   mymux "github.com/gorilla/mux"
   "net/http"
   "strconv"
)

func DecodeUserRequest(c context.Context, r *http.Request) (interface{}, error) {

   vars := mymux.Vars(r)

   if uid, ok := vars["uid"]; ok {
      uid, _ := strconv.Atoi(uid)
      return UserRequest{
         Uid:    uid,
         Method: r.Method,
      }, nil
   }
   return nil, errors.New("参数错误")
}

func EncodeUserResponse(ctx context.Context, w http.ResponseWriter, response interface{}) error {
   w.Header().Set("Content-type", "application/json")
   return json.NewEncoder(w).Encode(response)
}

UserService.go

package Services

import "errors"

type IUserService interface {
   GetName(userid int) string
   DelUser(userid int) error
}

type UserService struct {
}

func (this UserService) GetName(userid int) string {
   if userid == 101 {
      return "jiang"
   }
   return "tao"
}

func (this UserService) DelUser(userid int) error {
   if userid == 101 {
      return errors.New("无权限")
   }
   return nil
}

UserEndpoint.go

package Services

import (
   "context"
   "fmt"
   "github.com/go-kit/kit/endpoint"
)

type UserRequest struct {
   Uid    int `json:"uid"`
   Method string
}

type UserResponse struct {
   Result string `json:"result"`
}

func GenUserEndpoint(userService IUserService) endpoint.Endpoint {
   return func(ctx context.Context, request interface{}) (response interface{}, err error) {
      r := request.(UserRequest)
      result := "nothing"
      if r.Method == "GET" {
         result = userService.GetName(r.Uid)
      } else if r.Method == "DELETE" {
         err := userService.DelUser(r.Uid)
         if err != nil {
            result = err.Error()
         } else {
            result = fmt.Sprintf("userid为%d删除成功", r.Uid)
         }
      }

      return UserResponse{Result: result}, nil
   }
}

你可能感兴趣的:(微服务,golang,微服务)