trpc.group/trpc-go/trpc-go@v1.0.3/restful/options.go (about) 1 // 2 // 3 // Tencent is pleased to support the open source community by making tRPC available. 4 // 5 // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 // All rights reserved. 7 // 8 // If you have downloaded a copy of the tRPC source code from Tencent, 9 // please note that tRPC source code is licensed under the Apache 2.0 License, 10 // A copy of the Apache 2.0 License is included in this file. 11 // 12 // 13 14 package restful 15 16 import ( 17 "context" 18 "net/http" 19 "time" 20 21 "github.com/valyala/fasthttp" 22 "trpc.group/trpc-go/trpc-go/codec" 23 "trpc.group/trpc-go/trpc-go/filter" 24 ) 25 26 // Options are restful router options. 27 type Options struct { 28 namespace string // global namespace 29 environment string // global environment 30 container string // global container name 31 set string // global set name 32 33 ServiceName string // tRPC service name 34 ServiceImpl interface{} // tRPC service impl 35 FilterFunc ExtractFilterFunc // extract tRPC service filter chain 36 ErrorHandler ErrorHandler // error handler 37 HeaderMatcher HeaderMatcher // header matcher 38 ResponseHandler CustomResponseHandler // custom response handler 39 FastHTTPErrHandler FastHTTPErrorHandler // fasthttp error handler 40 FastHTTPHeaderMatcher FastHTTPHeaderMatcher // fasthttp header matcher 41 FastHTTPRespHandler FastHTTPRespHandler // fasthttp custom response handler 42 DiscardUnknownParams bool // ignore unknown query params 43 Timeout time.Duration // timeout 44 } 45 46 // Option sets restful router options. 47 type Option func(*Options) 48 49 func (o *Options) rebuildHeaderMatcher() { 50 headerMatcher := o.HeaderMatcher 51 o.HeaderMatcher = func( 52 ctx context.Context, 53 w http.ResponseWriter, 54 r *http.Request, 55 serviceName, methodName string, 56 ) (context.Context, error) { 57 ctx, err := headerMatcher(ctx, w, r, serviceName, methodName) 58 if err != nil { 59 return nil, err 60 } 61 return withGlobalMsg(ctx, o), nil 62 } 63 64 fastHTTPHeaderMatcher := o.FastHTTPHeaderMatcher 65 o.FastHTTPHeaderMatcher = func( 66 ctx context.Context, 67 requestCtx *fasthttp.RequestCtx, 68 serviceName, methodName string, 69 ) (context.Context, error) { 70 ctx, err := fastHTTPHeaderMatcher(ctx, requestCtx, serviceName, methodName) 71 if err != nil { 72 return nil, err 73 } 74 return withGlobalMsg(ctx, o), nil 75 } 76 } 77 78 // WithNamespace returns an Option that set namespace. 79 func WithNamespace(namespace string) Option { 80 return func(o *Options) { 81 o.namespace = namespace 82 } 83 } 84 85 // WithEnvironment returns an Option that sets environment name. 86 func WithEnvironment(env string) Option { 87 return func(o *Options) { 88 o.environment = env 89 } 90 } 91 92 // WithContainer returns an Option that sets container name. 93 func WithContainer(container string) Option { 94 return func(o *Options) { 95 o.container = container 96 } 97 } 98 99 // WithSet returns an Option that sets set name. 100 func WithSet(set string) Option { 101 return func(o *Options) { 102 o.set = set 103 } 104 } 105 106 // WithServiceName returns an Option that sets tRPC service name for the restful router. 107 func WithServiceName(name string) Option { 108 return func(o *Options) { 109 o.ServiceName = name 110 } 111 } 112 113 // WithFilterFunc returns an Option that sets tRPC service filter chain extracting function 114 // for the restful router. 115 func WithFilterFunc(f ExtractFilterFunc) Option { 116 return func(o *Options) { 117 if getFilters := o.FilterFunc; getFilters != nil { 118 o.FilterFunc = func() filter.ServerChain { 119 return append(getFilters(), f()...) 120 } 121 } else { 122 o.FilterFunc = f 123 } 124 } 125 } 126 127 // WithErrorHandler returns an Option that sets error handler for the restful router. 128 func WithErrorHandler(errorHandler ErrorHandler) Option { 129 return func(o *Options) { 130 o.ErrorHandler = errorHandler 131 } 132 } 133 134 // WithHeaderMatcher returns an Option that sets header matcher for the restful router. 135 func WithHeaderMatcher(m HeaderMatcher) Option { 136 return func(o *Options) { 137 o.HeaderMatcher = m 138 } 139 } 140 141 // WithResponseHandler returns an Option that sets custom response handler for 142 // the restful router. 143 func WithResponseHandler(h CustomResponseHandler) Option { 144 return func(o *Options) { 145 o.ResponseHandler = h 146 } 147 } 148 149 // WithFastHTTPErrorHandler returns an Option that sets fasthttp error handler 150 // for the restful router. 151 func WithFastHTTPErrorHandler(errHandler FastHTTPErrorHandler) Option { 152 return func(o *Options) { 153 o.FastHTTPErrHandler = errHandler 154 } 155 } 156 157 // WithFastHTTPHeaderMatcher returns an Option that sets fasthttp header matcher 158 // for the restful router. 159 func WithFastHTTPHeaderMatcher(m FastHTTPHeaderMatcher) Option { 160 return func(o *Options) { 161 o.FastHTTPHeaderMatcher = m 162 } 163 } 164 165 // WithFastHTTPRespHandler returns an Option that sets fasthttp custom response 166 // handler for the restful router. 167 func WithFastHTTPRespHandler(h FastHTTPRespHandler) Option { 168 return func(o *Options) { 169 o.FastHTTPRespHandler = h 170 } 171 } 172 173 // WithDiscardUnknownParams returns an Option that sets whether to ignore unknown query params 174 // for the restful router. 175 func WithDiscardUnknownParams(i bool) Option { 176 return func(o *Options) { 177 o.DiscardUnknownParams = i 178 } 179 } 180 181 // WithTimeout returns an Option that sets timeout for the restful router. 182 func WithTimeout(t time.Duration) Option { 183 return func(o *Options) { 184 o.Timeout = t 185 } 186 } 187 188 // withGlobalMsg sets tRPC yaml global fields to ctx message. 189 func withGlobalMsg(ctx context.Context, o *Options) context.Context { 190 ctx, msg := codec.EnsureMessage(ctx) 191 msg.WithNamespace(o.namespace) 192 msg.WithEnvName(o.environment) 193 msg.WithCalleeContainerName(o.container) 194 msg.WithSetName(o.set) 195 return ctx 196 }