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