go get github.com/go-kit/kit
;go get github.com/gorilla/mux
;上代码
package main
import (
"context"
"encoding/json"
"errors"
"log"
"net/http"
"github.com/gorilla/mux"
httptransport "github.com/go-kit/kit/transport/http"
"github.com/go-kit/kit/endpoint"
)
type MyService interface {
Foo(context.Context, string) (string, error)
Bar(context.Context, int64) (bool, error)
}
type myService struct{}
func (s myService) Foo(ctx context.Context, str string) (string, error) {
return "foo" + str, nil
}
func (s myService) Bar(ctx context.Context, n int64) (bool, error) {
return n%2 == 0, nil
}
type fooRequest struct {
Str string `json:"str"`
}
type fooResponse struct {
Str string `json:"str"`
Err string `json:"err,omitempty"`
}
type barRequest struct {
N int64 `json:"n"`
}
type barResponse struct {
Result bool `json:"result"`
Err string `json:"err,omitempty"`
}
func makeFooEndpoint(svc MyService) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (interface{}, error) {
req := request.(fooRequest)
res, err := svc.Foo(ctx, req.Str)
if err != nil {
return fooResponse{res, err.Error()}, nil
}
return fooResponse{res, ""}, nil
}
}
func makeBarEndpoint(svc MyService) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (interface{}, error) {
req := request.(barRequest)
res, err := svc.Bar(ctx, req.N)
if err != nil {
return barResponse{res, err.Error()}, nil
}
return barResponse{res, ""}, nil
}
}
func decodeFooRequest(_ context.Context, r *http.Request) (interface{}, error) {
var req fooRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
return nil, err
}
return req, nil
}
func decodeBarRequest(_ context.Context, r *http.Request) (interface{}, error) {
var req barRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
return nil, err
}
return req, nil
}
func encodeResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
return json.NewEncoder(w).Encode(response)
}
func main() {
// Create a new service
svc := myService{}
// Create the endpoints
fooEndpoint := makeFooEndpoint(svc)
barEndpoint := makeBarEndpoint(svc)
// Create the router and register the endpoints
r := mux.NewRouter()
r.Methods("POST").Path("/foo").Handler(httptransport.NewServer(
fooEndpoint,
decodeFooRequest,
encodeResponse,
))
r.Methods("POST").Path("/bar").Handler(httptransport.NewServer(
barEndpoint,
decodeBarRequest,
encodeResponse,
))
// Start the server
log.Fatal(http.ListenAndServe(":8080", r))
}
执行命令 curl http://127.0.0.1:8080/foo -d '{"data":"111"}' -XPOST
响应{"str":"foo"}
目录结构
.
├── endpoints
│ └── my_endpoint.go
├── go.mod
├── go.sum
├── main.go
├── services
│ └── my_service.go
└── transports
└── my_transport.go
services/my_service.go
/**
* @date: 2023/2/18
* @desc: 服务层 业务具体实现
*/
package endpoints
import "context"
type MyServicer interface {
Foo(context.Context, string) (string, error)
Bar(context.Context, int64) (bool, error)
}
type MyService struct{}
func (s *MyService) Foo(ctx context.Context, str string) (string, error) {
return "foo" + str, nil
}
func (s *MyService) Bar(ctx context.Context, n int64) (bool, error) {
return n%2 == 0, nil
}
endpoints/endpoint.go
/**
* @date: 2023/2/18
* @desc: endpoints 层
*/
package endpoints
import (
"context"
"github.com/go-kit/kit/endpoint"
services "kit-demo/services"
)
type FooRequest struct {
Str string `json:"str"`
}
type FooResponse struct {
Str string `json:"str"`
Err string `json:"err,omitempty"`
}
type BarRequest struct {
N int64 `json:"n"`
}
type BarResponse struct {
Result bool `json:"result"`
Err string `json:"err,omitempty"`
}
func MakeFooEndpoint(svc services.MyServicer) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (interface{}, error) {
req := request.(FooRequest)
res, err := svc.Foo(ctx, req.Str)
if err != nil {
return FooResponse{res, err.Error()}, nil
}
return FooResponse{res, ""}, nil
}
}
func MakeBarEndpoint(svc services.MyServicer) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (interface{}, error) {
req := request.(BarRequest)
res, err := svc.Bar(ctx, req.N)
if err != nil {
return BarResponse{res, err.Error()}, nil
}
return BarResponse{res, ""}, nil
}
}
transports/my_transport.go
/**
* @date: 2023/2/18
* @desc: 传输层 http/rpc...
*/
package endpoints
import (
"context"
"encoding/json"
"github.com/go-kit/kit/endpoint"
httptransport "github.com/go-kit/kit/transport/http"
"github.com/gorilla/mux"
"kit-demo/endpoints"
"net/http"
)
func decodeFooRequest(_ context.Context, r *http.Request) (interface{}, error) {
var req endpoints.FooRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
return nil, err
}
return req, nil
}
func decodeBarRequest(_ context.Context, r *http.Request) (interface{}, error) {
var req endpoints.BarRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
return nil, err
}
return req, nil
}
func encodeResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
return json.NewEncoder(w).Encode(response)
}
// MakeHttpHandler make http handler use mux
func MakeHttpHandler(ctx context.Context, fooEndpoint, barEndpoint endpoint.Endpoint) http.Handler {
r := mux.NewRouter()
options := []httptransport.ServerOption{
httptransport.ServerErrorEncoder(httptransport.DefaultErrorEncoder),
}
r.Methods("POST").Path("/foo").Handler(httptransport.NewServer(
fooEndpoint,
decodeFooRequest,
encodeResponse,
options...,
))
r.Methods("POST").Path("/bar").Handler(httptransport.NewServer(
barEndpoint,
decodeBarRequest,
encodeResponse,
options...,
))
return r
}
main.go
package main
import (
"context"
"fmt"
"kit-demo/endpoints"
services "kit-demo/services"
transports "kit-demo/transports"
"net/http"
"os"
"os/signal"
"syscall"
)
func main() {
errChan := make(chan error)
// Create a new service
svc := services.MyService{}
ctx := context.Background()
// Create the endpoints
fooEndpoint := endpoints.MakeFooEndpoint(&svc)
barEndpoint := endpoints.MakeBarEndpoint(&svc)
r := transports.MakeHttpHandler(ctx, fooEndpoint, barEndpoint)
go func() {
fmt.Println("Http Server start at port:8080")
handler := r
errChan <- http.ListenAndServe(":8080", handler)
}()
go func() {
c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
errChan <- fmt.Errorf("%s", <-c)
}()
fmt.Println(<-errChan)
}