github.com/thetreep/go-swagger@v0.0.0-20240223100711-35af64f14f01/generator/templates/server/builder.gotmpl (about) 1 // Code generated by go-swagger; DO NOT EDIT. 2 3 4 {{ if .Copyright -}}// {{ comment .Copyright -}}{{ end }} 5 6 7 package {{.Package}} 8 {{ $package := .Package }} 9 10 // This file was generated by the swagger tool. 11 // Editing this file might prove futile when you re-run the swagger generate command 12 13 import ( 14 "context" 15 "fmt" 16 "io" 17 "net/http" 18 "strings" 19 20 "github.com/go-openapi/errors" 21 "github.com/go-openapi/loads" 22 "github.com/go-openapi/runtime" 23 "github.com/go-openapi/runtime/middleware" 24 "github.com/go-openapi/runtime/security" 25 "github.com/go-openapi/spec" 26 "github.com/go-openapi/strfmt" 27 "github.com/go-openapi/swag" 28 29 {{ imports .DefaultImports }} 30 {{ imports .Imports }} 31 ) 32 33 // New{{ pascalize .Name }}API creates a new {{ pascalize .Name }} instance 34 func New{{ pascalize .Name }}API(spec *loads.Document) *{{ pascalize .Name }}API { 35 return &{{ pascalize .Name }}API{ 36 handlers: make(map[string]map[string]http.Handler), 37 formats: strfmt.Default, 38 defaultConsumes: "{{ .DefaultConsumes }}", 39 defaultProduces: "{{ .DefaultProduces }}", 40 customConsumers: make(map[string]runtime.Consumer), 41 customProducers: make(map[string]runtime.Producer), 42 PreServerShutdown: func() { }, 43 ServerShutdown: func() { }, 44 spec: spec, 45 useSwaggerUI: false, 46 ServeError: errors.ServeError, 47 BasicAuthenticator: security.BasicAuth, 48 APIKeyAuthenticator: security.APIKeyAuth, 49 BearerAuthenticator: security.BearerAuth, 50 {{ range .Consumes }} 51 {{- if .Implementation }} 52 {{ pascalize .Name }}Consumer: {{ .Implementation }}, 53 {{- else }} 54 {{ pascalize .Name }}Consumer: runtime.ConsumerFunc(func(r io.Reader, target interface{}) error { 55 return errors.NotImplemented("{{.Name}} consumer has not yet been implemented") 56 }), 57 {{- end }} 58 {{- end }} 59 {{ range .Produces }} 60 {{- if .Implementation }} 61 {{ pascalize .Name }}Producer: {{ .Implementation }}, 62 {{- else }} 63 {{ pascalize .Name }}Producer: runtime.ProducerFunc(func(w io.Writer, data interface{}) error { 64 return errors.NotImplemented("{{.Name}} producer has not yet been implemented") 65 }), 66 {{- end }} 67 {{- end }} 68 {{ range .Operations }} 69 {{ if ne .Package $package }}{{ pascalize .Package }}{{ end }}{{ pascalize .Name }}Handler: 70 {{- if ne .Package $package }}{{ .PackageAlias }}.{{ end }}{{ pascalize .Name }}HandlerFunc(func(params {{ if ne .Package $package }}{{ .PackageAlias }}.{{end }} 71 {{- if $.GenOpts.StrictResponders}} 72 {{- pascalize .Name }}Params{{if .Authorized}}, principal {{if .PrincipalIsNullable }}*{{ end }}{{.Principal}}{{end}}) {{if ne .Package $package }}{{ .Package }}.{{ end }}{{ pascalize .Name }}Responder { 73 return {{if ne .Package $package }}{{ .Package }}.{{ end }}{{ pascalize .Name }}NotImplemented() 74 {{else}} 75 {{- pascalize .Name }}Params{{if .Authorized}}, principal {{if .PrincipalIsNullable }}*{{ end }}{{.Principal}}{{end}}) middleware.Responder { 76 return middleware.NotImplemented("operation {{ if ne .Package $package }}{{ .Package }}.{{ end }}{{pascalize .Name}} has not yet been implemented") 77 {{ end -}} 78 }), 79 {{- end }} 80 {{ range .SecurityDefinitions }} 81 {{- if .IsBasicAuth }} 82 // Applies when the Authorization header is set with the Basic scheme 83 {{ pascalize .ID }}Auth: func(user string, pass string) ({{if .PrincipalIsNullable }}*{{ end }}{{.Principal}}, error) { 84 return nil, errors.NotImplemented("basic auth ({{ .ID }}) has not yet been implemented") 85 }, 86 {{- end }} 87 {{- if .IsAPIKeyAuth }} 88 // Applies when the "{{ .Name }}" {{ .Source }} is set 89 {{ pascalize .ID }}Auth: func(token string) ({{if .PrincipalIsNullable }}*{{ end }}{{.Principal}}, error) { 90 return nil, errors.NotImplemented("api key auth ({{ .ID }}) {{.Name}} from {{.Source}} param [{{ .Name }}] has not yet been implemented") 91 }, 92 {{- end }} 93 {{- if .IsOAuth2 }} 94 {{ pascalize .ID }}Auth: func(token string, scopes []string) ({{if .PrincipalIsNullable }}*{{ end }}{{.Principal}}, error) { 95 return nil, errors.NotImplemented("oauth2 bearer auth ({{ .ID }}) has not yet been implemented") 96 }, 97 {{- end }} 98 {{- end }} 99 {{- if .SecurityDefinitions }} 100 // default authorizer is authorized meaning no requests are blocked 101 APIAuthorizer: security.Authorized(), 102 {{- end }} 103 } 104 } 105 106 /*{{ pascalize .Name }}API {{ if .Info }}{{ if .Info.Description }}{{.Info.Description}}{{ else }}the {{ humanize .Name }} API{{ end }}{{ end }} */ 107 type {{ pascalize .Name }}API struct { 108 spec *loads.Document 109 context *middleware.Context 110 handlers map[string]map[string]http.Handler 111 formats strfmt.Registry 112 customConsumers map[string]runtime.Consumer 113 customProducers map[string]runtime.Producer 114 defaultConsumes string 115 defaultProduces string 116 Middleware func(middleware.Builder) http.Handler 117 useSwaggerUI bool 118 119 // BasicAuthenticator generates a runtime.Authenticator from the supplied basic auth function. 120 // It has a default implementation in the security package, however you can replace it for your particular usage. 121 BasicAuthenticator func(security.UserPassAuthentication) runtime.Authenticator 122 123 // APIKeyAuthenticator generates a runtime.Authenticator from the supplied token auth function. 124 // It has a default implementation in the security package, however you can replace it for your particular usage. 125 APIKeyAuthenticator func(string, string, security.TokenAuthentication) runtime.Authenticator 126 127 // BearerAuthenticator generates a runtime.Authenticator from the supplied bearer token auth function. 128 // It has a default implementation in the security package, however you can replace it for your particular usage. 129 BearerAuthenticator func(string, security.ScopedTokenAuthentication) runtime.Authenticator 130 {{ range .Consumes }} 131 // {{ pascalize .Name }}Consumer registers a consumer for the following mime types: 132 {{- range .AllSerializers }} 133 // - {{ .MediaType }} 134 {{- end }} 135 {{ pascalize .Name }}Consumer runtime.Consumer 136 {{- end }} 137 {{ range .Produces}} 138 // {{ pascalize .Name }}Producer registers a producer for the following mime types: 139 {{- range .AllSerializers }} 140 // - {{ .MediaType }} 141 {{- end }} 142 {{ pascalize .Name }}Producer runtime.Producer 143 {{- end }} 144 {{ range .SecurityDefinitions}} 145 {{- if .IsBasicAuth}} 146 147 // {{ pascalize .ID }}Auth registers a function that takes username and password and returns a principal 148 // it performs authentication with basic auth 149 {{ pascalize .ID }}Auth func(string, string) ({{ if .PrincipalIsNullable }}*{{ end }}{{ .Principal }}, error) 150 {{- end }} 151 {{- if .IsAPIKeyAuth}} 152 153 // {{ pascalize .ID }}Auth registers a function that takes a token and returns a principal 154 // it performs authentication based on an api key {{ .Name }} provided in the {{.Source}} 155 {{ pascalize .ID }}Auth func(string) ({{ if .PrincipalIsNullable }}*{{ end }}{{ .Principal }}, error) 156 {{- end }} 157 {{- if .IsOAuth2 }} 158 159 // {{ pascalize .ID }}Auth registers a function that takes an access token and a collection of required scopes and returns a principal 160 // it performs authentication based on an oauth2 bearer token provided in the request 161 {{ pascalize .ID }}Auth func(string, []string) ({{ if .PrincipalIsNullable }}*{{ end }}{{ .Principal }}, error) 162 {{- end }} 163 {{- end }} 164 {{- if .SecurityDefinitions }} 165 166 // APIAuthorizer provides access control (ACL/RBAC/ABAC) by providing access to the request and authenticated principal 167 APIAuthorizer runtime.Authorizer 168 {{- end }} 169 {{- $package := .Package }} 170 {{ range .Operations }} 171 // {{ if ne .Package $package }}{{ pascalize .Package }}{{ end }}{{ pascalize .Name }}Handler sets the operation handler for the {{ humanize .Name }} operation 172 {{ if ne .Package $package }}{{ pascalize .Package }}{{ end }}{{ pascalize .Name }}Handler {{ if ne .Package $package }}{{ .PackageAlias }}.{{ end }}{{ pascalize .Name }}Handler 173 {{- end }} 174 175 // ServeError is called when an error is received, there is a default handler 176 // but you can set your own with this 177 ServeError func(http.ResponseWriter, *http.Request, error) 178 179 // PreServerShutdown is called before the HTTP(S) server is shutdown 180 // This allows for custom functions to get executed before the HTTP(S) server stops accepting traffic 181 PreServerShutdown func() 182 183 // ServerShutdown is called when the HTTP(S) server is shut down and done 184 // handling all active connections and does not accept connections any more 185 ServerShutdown func() 186 187 // Custom command line argument groups with their descriptions 188 CommandLineOptionsGroups []swag.CommandLineOptionsGroup 189 190 // User defined logger function. 191 Logger func(string, ...interface{}) 192 } 193 194 // UseRedoc for documentation at /docs 195 func ({{.ReceiverName}} *{{ pascalize .Name }}API) UseRedoc() { 196 {{.ReceiverName}}.useSwaggerUI = false 197 } 198 199 // UseSwaggerUI for documentation at /docs 200 func ({{.ReceiverName}} *{{ pascalize .Name }}API) UseSwaggerUI() { 201 {{.ReceiverName}}.useSwaggerUI = true 202 } 203 204 // SetDefaultProduces sets the default produces media type 205 func ({{.ReceiverName}} *{{ pascalize .Name }}API) SetDefaultProduces(mediaType string) { 206 {{.ReceiverName}}.defaultProduces = mediaType 207 } 208 209 // SetDefaultConsumes returns the default consumes media type 210 func ({{.ReceiverName}} *{{ pascalize .Name }}API) SetDefaultConsumes(mediaType string) { 211 {{.ReceiverName}}.defaultConsumes = mediaType 212 } 213 214 // SetSpec sets a spec that will be served for the clients. 215 func ({{.ReceiverName}} *{{ pascalize .Name }}API) SetSpec(spec *loads.Document) { 216 {{.ReceiverName}}.spec = spec 217 } 218 219 // DefaultProduces returns the default produces media type 220 func ({{.ReceiverName}} *{{ pascalize .Name }}API) DefaultProduces() string { 221 return {{.ReceiverName}}.defaultProduces 222 } 223 224 // DefaultConsumes returns the default consumes media type 225 func ({{.ReceiverName}} *{{ pascalize .Name }}API) DefaultConsumes() string { 226 return {{.ReceiverName}}.defaultConsumes 227 } 228 229 // Formats returns the registered string formats 230 func ({{.ReceiverName}} *{{ pascalize .Name }}API) Formats() strfmt.Registry { 231 return {{.ReceiverName}}.formats 232 } 233 234 // RegisterFormat registers a custom format validator 235 func ({{.ReceiverName}} *{{ pascalize .Name }}API) RegisterFormat(name string, format strfmt.Format, validator strfmt.Validator) { 236 {{.ReceiverName}}.formats.Add(name, format, validator) 237 } 238 239 // Validate validates the registrations in the {{ pascalize .Name }}API 240 func ({{.ReceiverName}} *{{ pascalize .Name }}API) Validate() error { 241 var unregistered []string 242 {{ range .Consumes }} 243 if {{.ReceiverName}}.{{ pascalize .Name }}Consumer == nil { 244 unregistered = append(unregistered, "{{ pascalize .Name }}Consumer") 245 } 246 {{- end }} 247 {{ range .Produces }} 248 if {{.ReceiverName}}.{{ pascalize .Name }}Producer == nil { 249 unregistered = append(unregistered, "{{ pascalize .Name }}Producer") 250 } 251 {{- end }} 252 {{ range .SecurityDefinitions }} 253 if {{.ReceiverName}}.{{ pascalize .ID }}Auth == nil { 254 unregistered = append(unregistered, "{{if .IsAPIKeyAuth }}{{ pascalize .Name }}{{ else }}{{ pascalize .ID }}{{ end }}Auth") 255 } 256 {{- end }} 257 {{ range .Operations }} 258 if {{.ReceiverName}}.{{ if ne .Package $package }}{{ pascalize .Package }}{{ end }}{{ pascalize .Name }}Handler == nil { 259 unregistered = append(unregistered, "{{ if ne .Package $package }}{{ .Package }}.{{ end }}{{ pascalize .Name }}Handler") 260 } 261 {{- end }} 262 263 if len(unregistered) > 0 { 264 return fmt.Errorf("missing registration: %s", strings.Join(unregistered, ", ")) 265 } 266 267 return nil 268 } 269 // ServeErrorFor gets a error handler for a given operation id 270 func ({{.ReceiverName}} *{{ pascalize .Name }}API) ServeErrorFor(operationID string) func(http.ResponseWriter, *http.Request, error) { 271 return {{.ReceiverName}}.ServeError 272 } 273 // AuthenticatorsFor gets the authenticators for the specified security schemes 274 func ({{.ReceiverName}} *{{ pascalize .Name }}API) AuthenticatorsFor(schemes map[string]spec.SecurityScheme) map[string]runtime.Authenticator { 275 {{- if .SecurityDefinitions }} 276 result := make(map[string]runtime.Authenticator) 277 for name := range schemes { 278 switch name { 279 {{- range .SecurityDefinitions }} 280 case "{{.ID}}": 281 {{- if .IsBasicAuth }} 282 result[name] = {{.ReceiverName}}.BasicAuthenticator({{ if not ( eq .Principal "interface{}" ) }}func(username, password string) (interface{}, error) { 283 return {{ end }}{{.ReceiverName}}.{{ pascalize .ID }}Auth{{ if not ( eq .Principal "interface{}" ) }}(username, password) 284 }{{ end }}) 285 {{- end }} 286 {{- if .IsAPIKeyAuth }} 287 scheme := schemes[name] 288 result[name] = {{.ReceiverName}}.APIKeyAuthenticator(scheme.Name, scheme.In, {{ if not ( eq .Principal "interface{}" ) }}func(token string) (interface{}, error) { 289 return {{ end }}{{.ReceiverName}}.{{ pascalize .ID }}Auth{{ if not ( eq .Principal "interface{}" ) }}(token) 290 }{{ end }}) 291 {{- end }} 292 {{- if .IsOAuth2 }} 293 result[name] = {{.ReceiverName}}.BearerAuthenticator(name, {{ if not ( eq .Principal "interface{}" ) }}func(token string, scopes []string) (interface{}, error) { 294 return {{ end }}{{.ReceiverName}}.{{ pascalize .ID }}Auth{{ if not ( eq .Principal "interface{}" ) }}(token, scopes) 295 }{{ end }}) 296 {{- end }} 297 {{end}} 298 } 299 } 300 return result 301 {{- else }} 302 return nil 303 {{- end }} 304 } 305 306 // Authorizer returns the registered authorizer 307 func ({{.ReceiverName}} *{{ pascalize .Name }}API) Authorizer() runtime.Authorizer { 308 {{- if .SecurityDefinitions }} 309 return {{.ReceiverName}}.APIAuthorizer 310 {{- else }} 311 return nil 312 {{- end }} 313 } 314 315 // ConsumersFor gets the consumers for the specified media types. 316 // MIME type parameters are ignored here. 317 func ({{.ReceiverName}} *{{ pascalize .Name }}API) ConsumersFor(mediaTypes []string) map[string]runtime.Consumer { 318 {{- if .Consumes }} 319 result := make(map[string]runtime.Consumer, len(mediaTypes)) 320 for _, mt := range mediaTypes { 321 switch mt { 322 {{- range .Consumes }} 323 {{- range .AllSerializers }} 324 case "{{ .MediaType }}": 325 result["{{ .MediaType }}"] = {{.ReceiverName}}.{{ pascalize .Name }}Consumer 326 {{- end }} 327 {{- end }} 328 } 329 330 if c, ok := {{.ReceiverName}}.customConsumers[mt]; ok { 331 result[mt] = c 332 } 333 } 334 return result 335 {{- else }} 336 return nil 337 {{- end }} 338 } 339 340 // ProducersFor gets the producers for the specified media types. 341 // MIME type parameters are ignored here. 342 func ({{.ReceiverName}} *{{ pascalize .Name }}API) ProducersFor(mediaTypes []string) map[string]runtime.Producer { 343 {{- if .Produces }} 344 result := make(map[string]runtime.Producer, len(mediaTypes)) 345 for _, mt := range mediaTypes { 346 switch mt { 347 {{- range .Produces }} 348 {{- range .AllSerializers }} 349 case "{{ .MediaType }}": 350 result["{{ .MediaType }}"] = {{.ReceiverName}}.{{ pascalize .Name }}Producer 351 {{- end }} 352 {{- end }} 353 } 354 355 if p, ok := {{.ReceiverName}}.customProducers[mt]; ok { 356 result[mt] = p 357 } 358 } 359 return result 360 {{- else }} 361 return nil 362 {{- end }} 363 } 364 365 // HandlerFor gets a http.Handler for the provided operation method and path 366 func ({{.ReceiverName}} *{{ pascalize .Name }}API) HandlerFor(method, path string) (http.Handler, bool) { 367 if {{.ReceiverName}}.handlers == nil { 368 return nil, false 369 } 370 um := strings.ToUpper(method) 371 if _, ok := {{.ReceiverName}}.handlers[um]; !ok { 372 return nil, false 373 } 374 if path == "/" { 375 path = "" 376 } 377 h, ok := {{.ReceiverName}}.handlers[um][path] 378 return h, ok 379 } 380 381 // Context returns the middleware context for the {{ humanize .Name }} API 382 func ({{.ReceiverName}} *{{ pascalize .Name }}API) Context() *middleware.Context { 383 if {{.ReceiverName}}.context == nil { 384 {{.ReceiverName}}.context = middleware.NewRoutableContext({{.ReceiverName}}.spec, {{.ReceiverName}}, nil) 385 } 386 387 return {{ .ReceiverName }}.context 388 } 389 390 func ({{.ReceiverName}} *{{ pascalize .Name }}API) initHandlerCache() { 391 {{.ReceiverName}}.Context() // don't care about the result, just that the initialization happened 392 {{- if .Operations }} 393 if {{ .ReceiverName }}.handlers == nil { 394 {{.ReceiverName}}.handlers = make(map[string]map[string]http.Handler) 395 } 396 {{ range .Operations }} 397 if {{ .ReceiverName }}.handlers[{{ printf "%q" (upper .Method) }}] == nil { 398 {{ .ReceiverName }}.handlers[{{ printf "%q" (upper .Method) }}] = make(map[string]http.Handler) 399 } 400 {{.ReceiverName}}.handlers[{{ printf "%q" (upper .Method) }}][{{ if eq .Path "/" }}""{{ else }}{{ printf "%q" (cleanPath .Path) }}{{ end }}] = {{ if ne .Package $package }}{{ .PackageAlias }}.{{ end }}New{{ pascalize .Name }}({{.ReceiverName}}.context, {{.ReceiverName}}.{{if ne .Package $package}}{{ pascalize .Package }}{{end}}{{ pascalize .Name }}Handler) 401 {{- end }} 402 {{- end }} 403 } 404 405 // Serve creates a http handler to serve the API over HTTP 406 // can be used directly in http.ListenAndServe(":8000", api.Serve(nil)) 407 func ({{.ReceiverName}} *{{ pascalize .Name }}API) Serve(builder middleware.Builder) http.Handler { 408 {{ .ReceiverName }}.Init() 409 410 if {{ .ReceiverName}}.Middleware != nil { 411 return {{ .ReceiverName }}.Middleware(builder) 412 } 413 if {{.ReceiverName}}.useSwaggerUI { 414 return {{.ReceiverName}}.context.APIHandlerSwaggerUI(builder) 415 } 416 return {{.ReceiverName}}.context.APIHandler(builder) 417 } 418 419 // Init allows you to just initialize the handler cache, you can then recompose the middleware as you see fit 420 func ({{.ReceiverName}} *{{ pascalize .Name }}API) Init() { 421 if len({{.ReceiverName}}.handlers) == 0 { 422 {{.ReceiverName}}.initHandlerCache() 423 } 424 } 425 426 // RegisterConsumer allows you to add (or override) a consumer for a media type. 427 func ({{.ReceiverName}} *{{ pascalize .Name }}API) RegisterConsumer(mediaType string, consumer runtime.Consumer) { 428 {{.ReceiverName}}.customConsumers[mediaType] = consumer 429 } 430 431 // RegisterProducer allows you to add (or override) a producer for a media type. 432 func ({{.ReceiverName}} *{{ pascalize .Name }}API) RegisterProducer(mediaType string, producer runtime.Producer) { 433 {{.ReceiverName}}.customProducers[mediaType] = producer 434 } 435 436 // AddMiddlewareFor adds a http middleware to existing handler 437 func ({{.ReceiverName}} *{{ pascalize .Name }}API) AddMiddlewareFor(method, path string, builder middleware.Builder) { 438 um := strings.ToUpper(method) 439 if path == "/" { 440 path = "" 441 } 442 {{.ReceiverName}}.Init() 443 if h, ok := {{.ReceiverName}}.handlers[um][path]; ok { 444 {{.ReceiverName}}.handlers[um][path] = builder(h) 445 } 446 }