本文主要为个人记录,首先实现的是一个简单的基于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
测试