goKit微服务系列文章一:http rest

在这里插入图片描述
本文主要为个人记录,首先实现的是一个简单的基于HTTP的微服务实例,将以REST形式对外暴露,具体要求如下:

  • 使用gokit构建REST接口;
  • URL格式为:/calculate/{type}/{a}/{b},请求方法为POST;
    server.go 文件
/*
@Time : 2020/6/20 10:20
@Author : zhb
@File : server
@Software: GoLand
*/
package main

import "errors"

type Server interface {
    
    
	Add(a, b int) int
	Sub(a, b int) int
	Mul(a, b int) int
	Div(a, b int) (int, error)
}
type ArithmeticService struct {
    
    
}

func (t ArithmeticService) Add(a, b int) int {
    
    
	return a + b
}
func (t ArithmeticService) Sub(a, b int) int {
    
    
	return a - b
}
func (t ArithmeticService) Mul(a, b int) int {
    
    
	return a * b
}
func (t ArithmeticService) Div(a, b int) (int, error) {
    
    
	if b == 0 {
    
    
		return 0, errors.New("the dividend can not be zero!")
	}

	return a / b, nil
}

type ServerMiddleware struct {
    
    
}

endpoints.go文件

/*
@Time : 2020/6/20 10:26
@Author : zhb
@File : endpoints
@Software: GoLand
*/
package main

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

var (
	ErrInvalidRequestType = errors.New("RequestType has only four type: Add,Subtract,Multiply,Divide")
)

type ArithmeticRequst struct {
    
    
	RequestType string `json:"requst_type"`
	A           int    `json:"a"`
	B           int    `json:"b"`
}
type ArithmeticResponse struct {
    
    
	Result int   `json:"result"`
	Error  error `json:"error"`
}

type ArithmeticEndpoint endpoint.Endpoint

func MakeArithmeticEndpoint(s Server) endpoint.Endpoint {
    
    

	return func(ctx context.Context, request interface{
    
    }) (response interface{
    
    }, err error) {
    
    
		req := request.(ArithmeticRequst)
		var (
			result, a, b  int
			callbackerErr error
		)
		a = req.A
		b = req.B
		switch req.RequestType {
    
    
		case "add":
			result = s.Add(a, b)
		case "sub":
			result = s.Sub(a, b)
		case "mul":
			result = s.Mul(a, b)
		case "div":
			result, callbackerErr = s.Div(a, b)
		default:
			result = s.Add(a, b)
		}
		return result, callbackerErr
	}
}

tranports.go文件

/*
@Time : 2020/6/20 11:06
@Author : zhb
@File : transports
@Software: GoLand
*/
package main

import (
	"context"
	"encoding/json"
	"errors"
	"github.com/go-kit/kit/endpoint"
	"github.com/go-kit/kit/log"
	kithttp "github.com/go-kit/kit/transport/http"
	"github.com/gorilla/mux"
	"net/http"
	"strconv"
)

var (
	ErrorBadRequest = errors.New("invalid request parameter")
)

func MakeHttpHandler(ctx context.Context, endpoint endpoint.Endpoint, logger log.Logger) http.Handler {
    
    
	r := mux.NewRouter()
	options := []kithttp.ServerOption{
    
    
		kithttp.ServerErrorLogger(logger),
		kithttp.ServerErrorEncoder(kithttp.DefaultErrorEncoder),
	}

	r.Methods("POST").Path("/calculate/{type}/{a}/{b}").Handler(kithttp.NewServer(
		endpoint,
		decodeArithmeticRequest,
		encodeArithmeticResponse,
		options...,
	))

	//r.Path("/metrics").Handler(promhttp.Handler())

	return r
}

//解码
func decodeArithmeticRequest(_ context.Context, r *http.Request) (interface{
    
    }, error) {
    
    
	vars := mux.Vars(r)
	requestType, ok := vars["type"]
	if !ok {
    
    
		return nil, ErrorBadRequest
	}

	pa, ok := vars["a"]
	if !ok {
    
    
		return nil, ErrorBadRequest
	}

	pb, ok := vars["b"]
	if !ok {
    
    
		return nil, ErrorBadRequest
	}

	a, _ := strconv.Atoi(pa)
	b, _ := strconv.Atoi(pb)

	return ArithmeticRequst{
    
    
		RequestType: requestType,
		A:           a,
		B:           b,
	}, nil
}

// 转码
func encodeArithmeticResponse(ctx context.Context, w http.ResponseWriter, response interface{
    
    }) error {
    
    
	w.Header().Set("Content-Type", "application/json;charset=utf-8")
	return json.NewEncoder(w).Encode(response)
}

最后在来个main.go

/*
@Time : 2020/6/20 11:27
@Author : zhb
@File : main
@Software: GoLand
*/
package main

import (
	"context"
	"fmt"
	"github.com/go-kit/kit/log"
	"net/http"
	"os"
	"os/signal"
	"syscall"
)

func main() {
    
    

	ctx := context.Background()
	errChan := make(chan error)

	var svc Server
	svc = ArithmeticService{
    
    }
	endpoint := MakeArithmeticEndpoint(svc)

	var logger log.Logger
	{
    
    
		logger = log.NewLogfmtLogger(os.Stderr)
		logger = log.With(logger, "ts", log.DefaultTimestampUTC)
		logger = log.With(logger, "caller", log.DefaultCaller)
	}

	r := MakeHttpHandler(ctx, endpoint, logger)

	go func() {
    
    
		fmt.Println("Http Server start at port:9000")
		errChan <- http.ListenAndServe(":9000", r)
	}()

	go func() {
    
    
		c := make(chan os.Signal, 1)
		signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
		errChan <- fmt.Errorf("%s", <-c)
	}()

	fmt.Println(<-errChan)
}

最后启动一下main
测试
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_39998006/article/details/106869827