go.uber.org/yarpc@v1.72.1/call.go (about)

     1  // Copyright (c) 2022 Uber Technologies, Inc.
     2  //
     3  // Permission is hereby granted, free of charge, to any person obtaining a copy
     4  // of this software and associated documentation files (the "Software"), to deal
     5  // in the Software without restriction, including without limitation the rights
     6  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     7  // copies of the Software, and to permit persons to whom the Software is
     8  // furnished to do so, subject to the following conditions:
     9  //
    10  // The above copyright notice and this permission notice shall be included in
    11  // all copies or substantial portions of the Software.
    12  //
    13  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    14  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    15  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    16  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    17  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    18  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    19  // THE SOFTWARE.
    20  
    21  package yarpc
    22  
    23  import (
    24  	"context"
    25  
    26  	"go.uber.org/yarpc/api/encoding"
    27  	"go.uber.org/yarpc/api/transport"
    28  )
    29  
    30  // CallOption defines options that may be passed in at call sites to other
    31  // services.
    32  //
    33  // These may be used to add or alter the request.
    34  type CallOption encoding.CallOption
    35  
    36  // ResponseHeaders specifies that headers received in response to this request
    37  // should replace the given map.
    38  //
    39  // Header keys in the map are normalized using the CanonicalizeHeaderKey
    40  // function.
    41  //
    42  // 	var resHeaders map[string]string
    43  // 	resBody, err := client.SetValue(ctx, key, value, yarpc.ResponseHeaders(&resHeaders))
    44  // 	value, ok := resHeaders[yarpc.CanonicalizeHeaderKey("foo")]
    45  //
    46  // Note that the map is replaced completely. Entries it had before making the
    47  // call will not be available afterwards.
    48  //
    49  // 	headers := map[string]string{"hello": "world"}
    50  // 	resBody, err := client.SetValue(ctx, key, value, yarpc.ResponseHeaders(&headers))
    51  // 	_, ok := headers["hello"]
    52  // 	fmt.Println(ok)  // false
    53  func ResponseHeaders(h *map[string]string) CallOption {
    54  	return CallOption(encoding.ResponseHeaders(h))
    55  }
    56  
    57  // WithHeader adds a new header to the request. Header keys are case
    58  // insensitive.
    59  //
    60  // 	_, err := client.GetValue(ctx, reqBody, yarpc.WithHeader("Token", "10"))
    61  // 	// ==> {"token": "10"}
    62  //
    63  // If multiple entries have the same normalized header name, newer entries
    64  // override older ones.
    65  func WithHeader(k, v string) CallOption {
    66  	return CallOption(encoding.WithHeader(k, v))
    67  }
    68  
    69  // WithShardKey sets the shard key for the request.
    70  func WithShardKey(sk string) CallOption {
    71  	return CallOption(encoding.WithShardKey(sk))
    72  }
    73  
    74  // WithRoutingKey sets the routing key for the request.
    75  func WithRoutingKey(rk string) CallOption {
    76  	return CallOption(encoding.WithRoutingKey(rk))
    77  }
    78  
    79  // WithRoutingDelegate sets the routing delegate for the request.
    80  func WithRoutingDelegate(rd string) CallOption {
    81  	return CallOption(encoding.WithRoutingDelegate(rd))
    82  }
    83  
    84  // Call provides information about the current request inside handlers. An
    85  // instance of Call for the current request can be obtained by calling
    86  // CallFromContext on the request context.
    87  //
    88  // 	func Get(ctx context.Context, req *GetRequest) (*GetResponse, error) {
    89  // 		call := yarpc.CallFromContext(ctx)
    90  // 		fmt.Println("Received request from", call.Caller())
    91  // 		if err := call.WriteResponseHeader("hello", "world"); err != nil {
    92  // 			return nil, err
    93  // 		}
    94  // 		return response, nil
    95  // 	}
    96  type Call encoding.Call
    97  
    98  // CallFromContext retrieves information about the current incoming request
    99  // from the given context. Returns nil if the context is not a valid request
   100  // context.
   101  //
   102  // The object is valid only as long as the request is ongoing.
   103  //
   104  // Testing
   105  //
   106  // To test functions which use CallFromContext, use yarpctest.ContextWithCall
   107  // to build contexts compatible with this function.
   108  func CallFromContext(ctx context.Context) *Call {
   109  	return (*Call)(encoding.CallFromContext(ctx))
   110  }
   111  
   112  // WriteResponseHeader writes headers to the response of this call.
   113  func (c *Call) WriteResponseHeader(k, v string) error {
   114  	return (*encoding.Call)(c).WriteResponseHeader(k, v)
   115  }
   116  
   117  // Caller returns the name of the service making this request.
   118  func (c *Call) Caller() string {
   119  	return (*encoding.Call)(c).Caller()
   120  }
   121  
   122  // Service returns the name of the service being called.
   123  func (c *Call) Service() string {
   124  	return (*encoding.Call)(c).Service()
   125  }
   126  
   127  // Transport returns the name of the transport being called.
   128  func (c *Call) Transport() string {
   129  	return (*encoding.Call)(c).Transport()
   130  }
   131  
   132  // Procedure returns the name of the procedure being called.
   133  func (c *Call) Procedure() string {
   134  	return (*encoding.Call)(c).Procedure()
   135  }
   136  
   137  // Encoding returns the encoding for this request.
   138  func (c *Call) Encoding() transport.Encoding {
   139  	return (*encoding.Call)(c).Encoding()
   140  }
   141  
   142  // Header returns the value of the given request header provided with the
   143  // request.
   144  func (c *Call) Header(k string) string {
   145  	return (*encoding.Call)(c).Header(k)
   146  }
   147  
   148  // OriginalHeaders returns a copy of the given request headers provided with the request.
   149  // The header key are not canonicalized and suitable for case-sensitive transport like TChannel.
   150  func (c *Call) OriginalHeaders() map[string]string {
   151  	return (*encoding.Call)(c).OriginalHeaders()
   152  }
   153  
   154  // HeaderNames returns a sorted list of the names of user defined headers
   155  // provided with this request.
   156  func (c *Call) HeaderNames() []string {
   157  	return (*encoding.Call)(c).HeaderNames()
   158  }
   159  
   160  // ShardKey returns the shard key for this request.
   161  func (c *Call) ShardKey() string {
   162  	return (*encoding.Call)(c).ShardKey()
   163  }
   164  
   165  // RoutingKey returns the routing key for this request.
   166  func (c *Call) RoutingKey() string {
   167  	return (*encoding.Call)(c).RoutingKey()
   168  }
   169  
   170  // RoutingDelegate returns the routing delegate for this request.
   171  func (c *Call) RoutingDelegate() string {
   172  	return (*encoding.Call)(c).RoutingDelegate()
   173  }
   174  
   175  // CallerProcedure returns the name of the procedure from the service making this request.
   176  func (c *Call) CallerProcedure() string {
   177  	return (*encoding.Call)(c).CallerProcedure()
   178  }
   179  
   180  // StreamOption defines options that may be passed in at streaming function
   181  // call sites.
   182  //
   183  // These may be used to add or alter individual stream calls.
   184  type StreamOption encoding.StreamOption