github.com/clubpay/ronykit/kit@v0.14.4-0.20240515065620-d0dace45cbc7/desc/contract.go (about) 1 package desc 2 3 import "github.com/clubpay/ronykit/kit" 4 5 type Header struct { 6 Name string 7 Required bool 8 } 9 10 func OptionalHeader(name string) Header { 11 return Header{ 12 Name: name, 13 Required: false, 14 } 15 } 16 17 func RequiredHeader(name string) Header { 18 return Header{ 19 Name: name, 20 Required: true, 21 } 22 } 23 24 type RouteSelector struct { 25 Name string 26 Selector kit.RouteSelector 27 } 28 29 // Contract is the description of the kit.Contract you are going to create. 30 type Contract struct { 31 Name string 32 Encoding kit.Encoding 33 Handlers []kit.HandlerFunc 34 Wrappers []kit.ContractWrapper 35 RouteSelectors []RouteSelector 36 EdgeSelector kit.EdgeSelectorFunc 37 Modifiers []kit.ModifierFunc 38 InputHeaders []Header 39 Input kit.Message 40 Output kit.Message 41 PossibleErrors []Error 42 } 43 44 func NewContract() *Contract { 45 return &Contract{} 46 } 47 48 // SetName sets the name of the Contract c, it MUST be unique per Service. However, it 49 // has no operation effect only is helpful with some other tools such as monitoring, 50 // logging or tracing tools to identity it. 51 func (c *Contract) SetName(name string) *Contract { 52 c.Name = name 53 54 return c 55 } 56 57 // SetEncoding sets the supported encoding for this contract. 58 func (c *Contract) SetEncoding(enc kit.Encoding) *Contract { 59 c.Encoding = enc 60 61 return c 62 } 63 64 // SetInputHeader sets the headers for this Contract. This is an OPTIONAL parameter, which 65 // could be used by external tools such as Swagger or any other doc generator tools. 66 func (c *Contract) SetInputHeader(headers ...Header) *Contract { 67 c.InputHeaders = headers 68 69 return c 70 } 71 72 // SetInput sets the accepting message for this Contract. Contracts are bound to one input message. 73 func (c *Contract) SetInput(m kit.Message) *Contract { 74 c.Input = m 75 76 return c 77 } 78 79 // In is an alias for SetInput 80 func (c *Contract) In(m kit.Message) *Contract { 81 return c.SetInput(m) 82 } 83 84 // SetOutput sets the outgoing message for this Contract. This is an OPTIONAL parameter, which 85 // mostly could be used by external tools such as Swagger or any other doc generator tools. 86 func (c *Contract) SetOutput(m kit.Message) *Contract { 87 c.Output = m 88 89 return c 90 } 91 92 // Out is an alias for SetOutput 93 func (c *Contract) Out(m kit.Message) *Contract { 94 return c.SetOutput(m) 95 } 96 97 // AddError sets the possible errors for this Contract. Using this method is OPTIONAL, which 98 // mostly could be used by external tools such as Swagger or any other doc generator tools. 99 func (c *Contract) AddError(err kit.ErrorMessage) *Contract { 100 c.PossibleErrors = append( 101 c.PossibleErrors, 102 Error{ 103 Code: err.GetCode(), 104 Item: err.GetItem(), 105 Message: err, 106 }, 107 ) 108 109 return c 110 } 111 112 // AddSelector adds a kit.RouteSelector for this contract. Selectors are bundle specific. 113 func (c *Contract) AddSelector(s ...kit.RouteSelector) *Contract { 114 for idx := range s { 115 c.RouteSelectors = append( 116 c.RouteSelectors, 117 RouteSelector{Name: "", Selector: s[idx]}, 118 ) 119 } 120 121 return c 122 } 123 124 // Selector is an alias for AddSelector 125 func (c *Contract) Selector(s ...kit.RouteSelector) *Contract { 126 return c.AddSelector(s...) 127 } 128 129 // AddNamedSelector adds a kit.RouteSelector for this contract, and assigns it a unique name. 130 // In case you need to use auto-generated stub.Stub for your service/contract this name will 131 // be used in the generated code. 132 func (c *Contract) AddNamedSelector(name string, s kit.RouteSelector) *Contract { 133 c.RouteSelectors = append(c.RouteSelectors, RouteSelector{ 134 Name: name, 135 Selector: s, 136 }) 137 138 return c 139 } 140 141 // NamedSelector is an alias for AddNamedSelector 142 func (c *Contract) NamedSelector(name string, s kit.RouteSelector) *Contract { 143 return c.AddNamedSelector(name, s) 144 } 145 146 // SetCoordinator sets a kit.EdgeSelectorFunc for this contract, to coordinate requests to 147 // right kit.EdgeServer instance. 148 func (c *Contract) SetCoordinator(f kit.EdgeSelectorFunc) *Contract { 149 c.EdgeSelector = f 150 151 return c 152 } 153 154 // Coordinator is an alias for SetCoordinator 155 func (c *Contract) Coordinator(f kit.EdgeSelectorFunc) *Contract { 156 return c.SetCoordinator(f) 157 } 158 159 // AddModifier adds a kit.ModifierFunc for this contract. Modifiers are used to modify 160 // the outgoing kit.Envelope just before sending to the client. 161 func (c *Contract) AddModifier(m kit.ModifierFunc) *Contract { 162 c.Modifiers = append(c.Modifiers, m) 163 164 return c 165 } 166 167 // AddWrapper adds a kit.ContractWrapper for this contract. 168 func (c *Contract) AddWrapper(wrappers ...kit.ContractWrapper) *Contract { 169 c.Wrappers = append(c.Wrappers, wrappers...) 170 171 return c 172 } 173 174 // AddHandler add handler for this contract. 175 func (c *Contract) AddHandler(h ...kit.HandlerFunc) *Contract { 176 c.Handlers = append(c.Handlers, h...) 177 178 return c 179 } 180 181 // SetHandler set the handler by replacing the already existing ones. 182 func (c *Contract) SetHandler(h ...kit.HandlerFunc) *Contract { 183 c.Handlers = append(c.Handlers[:0], h...) 184 185 return c 186 } 187 188 // contractImpl is a simple implementation of kit.Contract interface. 189 type contractImpl struct { 190 id string 191 routeSelector kit.RouteSelector 192 memberSelector kit.EdgeSelectorFunc 193 handlers []kit.HandlerFunc 194 modifiers []kit.ModifierFunc 195 input kit.Message 196 output kit.Message 197 enc kit.Encoding 198 } 199 200 var _ kit.Contract = (*contractImpl)(nil) 201 202 func (r *contractImpl) setInput(input kit.Message) *contractImpl { 203 r.input = input 204 205 return r 206 } 207 208 func (r *contractImpl) setOutput(output kit.Message) *contractImpl { 209 r.output = output 210 211 return r 212 } 213 214 func (r *contractImpl) setEncoding(enc kit.Encoding) *contractImpl { 215 r.enc = enc 216 217 return r 218 } 219 220 func (r *contractImpl) setRouteSelector(selector kit.RouteSelector) *contractImpl { 221 r.routeSelector = selector 222 223 return r 224 } 225 226 func (r *contractImpl) setMemberSelector(selector kit.EdgeSelectorFunc) *contractImpl { 227 r.memberSelector = selector 228 229 return r 230 } 231 232 func (r *contractImpl) addHandler(handlers ...kit.HandlerFunc) *contractImpl { 233 r.handlers = append(r.handlers, handlers...) 234 235 return r 236 } 237 238 func (r *contractImpl) setModifier(modifiers ...kit.ModifierFunc) *contractImpl { 239 r.modifiers = append(r.modifiers[:0], modifiers...) 240 241 return r 242 } 243 244 func (r *contractImpl) ID() string { 245 return r.id 246 } 247 248 func (r *contractImpl) RouteSelector() kit.RouteSelector { 249 return r.routeSelector 250 } 251 252 func (r *contractImpl) EdgeSelector() kit.EdgeSelectorFunc { 253 return r.memberSelector 254 } 255 256 func (r *contractImpl) Handlers() []kit.HandlerFunc { 257 return r.handlers 258 } 259 260 func (r *contractImpl) Modifiers() []kit.ModifierFunc { 261 return r.modifiers 262 } 263 264 func (r *contractImpl) Input() kit.Message { 265 return r.input 266 } 267 268 func (r *contractImpl) Output() kit.Message { 269 return r.output 270 } 271 272 func (r *contractImpl) Encoding() kit.Encoding { 273 return r.enc 274 }