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  }