HTTP
Network(network string) ServerOption
配置服务端的 network 协议,如 tcp
Address(addr string) ServerOption
配置服务端监听的地址
Timeout(timeout time.Duration) ServerOption
配置服务端的超时设置
Logger(logger log.Logger) ServerOption
配置服务端使用日志
Middleware(m ...middleware.Middleware) ServerOption
配置服务端的 kratos Service中间件
Filter(filters ...FilterFunc) ServerOption
配置服务端的 kratos 全局HTTP原生Fitler,此Filter执行顺序在Service中间件之前
RequestDecoder(dec DecodeRequestFunc) ServerOption
配置kratos服务端的 HTTP Request Decode方法,用来将Request Body解析至用户定义的pb结构体中 我们看下kratos中默认的RequestDecoder是怎么实现的:
那么如果我们想要扩展或者替换Content-Type对应的解析实现,就可以通过http.RequestDecoder()来替换kratos默认的RequestDecoder, 或者也可以通过在encoding中注册或覆盖一个Content-Type对应的codec来进行扩展
ResponseEncoder(en EncodeResponseFunc) ServerOption
配置kratos服务端的 HTTP Response Encode方法,用来将用户pb定义里的reply结构体序列化后写入Response Body中 我们看下kratos中默认的ResponseEncoder是怎么实现的:
func DefaultResponseEncoder(w http.ResponseWriter, r *http.Request, v interface{}) error {
// 通过Request Header的Accept中提取出对应的编码器
// 如果找不到则忽略报错,并使用默认json编码器
codec, _ := CodecForRequest(r, "Accept")
data, err := codec.Marshal(v)
if err != nil {
return err
}
w.Header().Set("Content-Type", httputil.ContentType(codec.Name()))
w.Write(data)
return nil
}
那么如果我们想要扩展或者替换Accept对应的序列化实现,就可以通过http.ResponseEncoder()来替换kratos默认的ResponseEncoder, 或者也可以通过在encoding中注册或覆盖一个Accept对应的codec来进行扩展
ErrorEncoder(en EncodeErrorFunc) ServerOption
func DefaultErrorEncoder(w http.ResponseWriter, r *http.Request, err error) {
// 拿到error并转换成kratos Error实体
se := errors.FromError(err)
codec, _ := CodecForRequest(r, "Accept")
body, err := codec.Marshal(se)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", httputil.ContentType(codec.Name()))
// 设置HTTP Status Code
w.WriteHeader(int(se.Code))
w.Write(body)
}
TLSConfig(c *tls.Config) ServerOption
为 kratos 服务端添加 tls 配置用于加密 http 通信 我们看下 kratos 中是如何配置的:
// TLSConfig with TLS config.
func TLSConfig(c *tls.Config) ServerOption {
return func(o *Server) {
o.tlsConf = c
}
}
StrictSlash(strictSlash bool) ServerOption
为 kratos 服务端添加 StrictSlash 配置,用于重定向路由 我们看下 kratos 中是如何配置的
// StrictSlash is with mux's StrictSlash
// If true, when the path pattern is "/path/", accessing "/path" will
// redirect to the former and vice versa.
func StrictSlash(strictSlash bool) ServerOption {
return func(o *Server) {
o.strictSlash = strictSlash
}
}
Listener(lis net.Listener) ServerOption
为 kratos 服务端添加 Listener 接口用于面向流协议的传输 我们看下 kratos 中是如何配置的
NewServer(opts ...ServerOption) *Server
传入opts配置并启动HTTP Server
hs := http.NewServer()
app := kratos.New(
kratos.Name("kratos"),
kratos.Version("v1.0.0"),
kratos.Server(hs),
)
HTTP server 中使用 kratos middleware
hs := http.NewServer(
http.Address(":8000"),
http.Middleware(
logging.Server(),
),
)
middleware 中处理 http 请求
if tr, ok := transport.FromServerContext(ctx); ok {
kind = tr.Kind().String()
operation = tr.Operation()
// 断言成HTTP的Transport可以拿到特殊信息
fmt.Println(ht.Request())
}
}
func (s *Server) Route(prefix string, filters ...FilterFunc) *Router
创建一个新的HTTP Server Router,同时可以传递kratos的HTTP Filter拦截器 我们看下用法:
r := s.Route("/v1")
r.GET("/helloworld/{name}", _Greeter_SayHello0_HTTP_Handler(srv))
func (s *Server) Handle(path string, h http.Handler)
将path添加到路由中,并使用标准的HTTP Handler来处理
func (s *Server) HandlePrefix(prefix string, h http.Handler)
前缀匹配的方式将prefix添加到路由中,并使用标准的HTTP Handler来处理
func (s *Server) ServeHTTP(res http.ResponseWriter, req *http.Request)
实现了标准库的HTTP Handler接口
Client
WithTimeout(d time.Duration) ClientOption
配置客户端的请求默认超时时间,如果有链路超时优先使用链路超时时间
WithUserAgent(ua string) ClientOption
配置客户端的默认User-Agent
WithMiddleware(m ...middleware.Middleware) ClientOption
配置客户端使用的 kratos client中间件
WithEndpoint(endpoint string) ClientOption
配置客户端使用的对端连接地址,如果不使用服务发现则为ip:port,如果使用服务发现则格式为discovery://\<authority>/\<serviceName>,这里\<authority>可以默认填空
WithDiscovery(d registry.Discovery) ClientOption
配置客户端使用的服务发现
WithRequestEncoder(encoder EncodeRequestFunc) ClientOption
配置客户端的 HTTP Request Encode方法,用来将户定义的pb结构体中序列化至Request Body 我们看下默认的encoder:
WithResponseDecoder(decoder DecodeResponseFunc) ClientOption
配置客户端的 HTTP Response Decode方法,用来将Response Body解析至用户定义的pb结构体中 我们看下kratos中默认的decoder是怎么实现的:
func DefaultResponseDecoder(ctx context.Context, res *http.Response, v interface{}) error {
defer res.Body.Close()
data, err := ioutil.ReadAll(res.Body)
if err != nil {
return err
}
// 这里根据Response Header中的Content-Type拿到对应的decoder
// 然后进行Unmarshal
return CodecForResponse(res).Unmarshal(data, v)
}
WithErrorDecoder(errorDecoder DecodeErrorFunc) ClientOption
配置客户端的Error解析方法 我们看下kratos中默认的error decoder是怎么实现的:
func DefaultErrorDecoder(ctx context.Context, res *http.Response) error {
// HTTP Status Code 为最高优先级
if res.StatusCode >= 200 && res.StatusCode <= 299 {
return nil
}
defer res.Body.Close()
data, err := ioutil.ReadAll(res.Body)
if err == nil {
e := new(errors.Error)
// 这里根据Response Header中的Content-Type拿到对应的response decoder
// 然后解析出error主体内容
if err = CodecForResponse(res).Unmarshal(data, e); err == nil {
// HTTP Status Code 为最高优先级
e.Code = int32(res.StatusCode)
return e
}
}
// 如果没有返回合法的Response Body则直接以HTTP Status Code为准
return errors.Errorf(res.StatusCode, errors.UnknownReason, err.Error())
}
WithBalancer(b balancer.Balancer) ClientOption
配置客户端的负载均衡策略
WithBlock() ClientOption
配置客户端的Dial策略为阻塞(直到服务发现发现节点才返回),默认为异步非阻塞
WithTLSConfig(c *tls.Config) ClientOption
// WithTLSConfig with tls config.
func WithTLSConfig(c *tls.Config) ClientOption {
return func(o *clientOptions) {
o.tlsConf = c
}
}
创建客户端连接
conn, err := http.NewClient(
context.Background(),
http.WithEndpoint("127.0.0.1:8000"),
)
使用中间件
使用服务发现
conn, err := http.NewClient(
context.Background(),
http.WithEndpoint("discovery:///helloworld"),
http.WithDiscovery(r),