// This file is safe to edit. Once it exists it will not be overwritten {{ if .Copyright -}}// {{ comment .Copyright -}}{{ end }} {{- $noDB := not (not (index .Info.Extensions "x-go-orusapi-no-db") ) }} package {{ .APIPackage }} import ( "context" "crypto/tls" "io" "log" "net/http" "github.com/go-openapi/errors" "github.com/go-openapi/runtime" "github.com/go-openapi/runtime/middleware" "github.com/go-openapi/runtime/security" "orus.io/orus-io/go-orusapi" {{ imports .DefaultImports }} {{ imports .Imports }} ) // Callback is a simple function type Callback func() // Config holds the things required to configure the API type Config struct { Log zerolog.Logger {{- if not $noDB }} DB *sqlx.DB {{- end }} BaseURL string Shutdown []Callback // Here you can add anything the ConfigureAPI function will need to setup // the API } {{ with .GenOpts }} //go:generate swagger generate server --target {{ .TargetPath }} --name {{ .Name }} --spec {{ .SpecPath }} {{- if .APIPackage }}{{ if ne .APIPackage "operations" }} --api-package {{ .APIPackage }}{{ end }}{{ end }} {{- if .ModelPackage }}{{ if ne .ModelPackage "models" }} --model-package {{ .ModelPackage }}{{ end }}{{ end }} {{- if .ServerPackage }}{{ if ne .ServerPackage "restapi"}} --server-package {{ .ServerPackage }}{{ end }}{{ end }} {{- if .ClientPackage }}{{ if ne .ClientPackage "client" }} --client-package {{ .ClientPackage }}{{ end }}{{ end }} {{- if .TemplateDir }} --template-dir {{ .TemplateDir }}{{ end }} {{- range .Operations }} --operation {{ . }}{{ end }} {{- range .Tags }} --tags {{ . }}{{ end }} {{- if .Principal }} --principal {{ .Principal }}{{ end }} {{- if .DefaultScheme }}{{ if ne .DefaultScheme "http" }} --default-scheme {{ .DefaultScheme }}{{ end }}{{ end }} {{- range .Models }} --model {{ . }}{{ end }} {{- if or (not .IncludeModel) (not .IncludeValidator) }} --skip-models{{ end }} {{- if or (not .IncludeHandler) (not .IncludeParameters ) (not .IncludeResponses) }} --skip-operations{{ end }} {{- if not .IncludeSupport }} --skip-support{{ end }} {{- if not .IncludeMain }} --exclude-main{{ end }} {{- if .ExcludeSpec }} --exclude-spec{{ end }} {{- if .DumpData }} --dump-data{{ end }} {{- if .StrictResponders }} --strict-responders{{ end }} {{ end }} type ConfiguredAPI struct { api *{{.Package}}.{{ pascalize .Name }}API handler http.Handler config Config } func (capi *ConfiguredAPI) Name() string { return "{{ .Name }}" } func (capi *ConfiguredAPI) Handler() http.Handler { return capi.handler } func (capi *ConfiguredAPI) PreServerShutdown() { } func (capi *ConfiguredAPI) ServerShutdown() { lsize := len(capi.config.Shutdown) for i := range capi.config.Shutdown { capi.config.Shutdown[lsize-i-1]() } } func ConfigureAPI(api *{{.Package}}.{{ pascalize .Name }}API, server *orusapi.Server, config Config) (*ConfiguredAPI, error) { // configure the api here api.ServeError = errors.ServeError if config.BaseURL == "" { scheme := "https" if len(server.EnabledListeners) != 0 { scheme = server.EnabledListeners[0] } config.BaseURL = fmt.Sprintf("%s://%s:%d", scheme, server.Host, server.Port, ) } // Set your custom logger if needed. Default one is log.Printf // Expected interface func(string, ...interface{}) // // Example: // api.Logger = log.Printf api.UseSwaggerUI() // To continue using redoc as your UI, uncomment the following line // api.UseRedoc() {{ range .Consumes }} {{- if .Implementation }} api.{{ pascalize .Name }}Consumer = {{ .Implementation }} {{- else }} api.{{ pascalize .Name }}Consumer = runtime.ConsumerFunc(func(r io.Reader, target interface{}) error { return errors.NotImplemented("{{.Name}} consumer has not yet been implemented") }) {{- end }} {{- end }} {{ range .Produces }} {{- if .Implementation }} api.{{ pascalize .Name }}Producer = {{ .Implementation }} {{- else }} api.{{ pascalize .Name }}Producer = runtime.ProducerFunc(func(w io.Writer, data interface{}) error { return errors.NotImplemented("{{.Name}} producer has not yet been implemented") }) {{- end }} {{- end}} {{ range .SecurityDefinitions }} {{- if .IsBasicAuth }} // Applies when the Authorization header is set with the Basic scheme if api.{{ pascalize .ID }}Auth == nil { api.{{ pascalize .ID }}Auth = func(user string, pass string) ({{if not ( eq .Principal "interface{}" )}}*{{ end }}{{.Principal}}, error) { return nil, errors.NotImplemented("basic auth ({{ .ID }}) has not yet been implemented") } } {{- else if .IsAPIKeyAuth }} // Applies when the "{{ .Name }}" {{ .Source }} is set if api.{{ pascalize .ID }}Auth == nil { api.{{ pascalize .ID }}Auth = func(token string) ({{if not ( eq .Principal "interface{}" )}}*{{ end }}{{.Principal}}, error) { return nil, errors.NotImplemented("api key auth ({{ .ID }}) {{.Name}} from {{.Source}} param [{{ .Name }}] has not yet been implemented") } } {{- else if .IsOAuth2 }} if api.{{ pascalize .ID }}Auth == nil { api.{{ pascalize .ID }}Auth = func(token string, scopes []string) ({{if not ( eq .Principal "interface{}" )}}*{{ end }}{{.Principal}}, error) { return nil, errors.NotImplemented("oauth2 bearer auth ({{ .ID }}) has not yet been implemented") } } {{- end }} {{- end }} {{- if .SecurityDefinitions }} // Set your custom authorizer if needed. Default one is security.Authorized() // Expected interface runtime.Authorizer // // Example: // api.APIAuthorizer = security.Authorized() {{- end }} {{- $package := .Package }} {{- range .Operations }} if api.{{ if ne .Package $package }}{{ pascalize .Package }}{{ end }}{{ pascalize .Name }}Handler == nil { api.{{ if ne .Package $package }}{{pascalize .Package}}{{ end }}{{ pascalize .Name }}Handler = {{- .PackageAlias }}.{{- pascalize .Name }}HandlerFunc(func(params {{ .PackageAlias }}.{{- pascalize .Name }}Params {{- if $.GenOpts.StrictResponders }} {{- if .Authorized}}, principal {{if not ( eq .Principal "interface{}" )}}*{{ end }}{{.Principal}}{{end}}) {{.Package}}.{{ pascalize .Name }}Responder { return {{.Package}}.{{ pascalize .Name }}NotImplemented() {{ else }} {{- if .Authorized}}, principal {{if not ( eq .Principal "interface{}" )}}*{{ end }}{{.Principal}}{{end}}) middleware.Responder { return middleware.NotImplemented("operation {{ .Package}}.{{pascalize .Name}} has not yet been implemented") {{ end -}} }) } {{- end }} if server.Prometheus { api.PrometheusInstrumentHandlers() } api.LoggingInstrumentHandlers() return &ConfiguredAPI{ api: api, handler: setupGlobalMiddleware(api.Serve(setupMiddlewares)), config: config, }, nil } // The TLS configuration before HTTPS server starts. //func configureTLS(tlsConfig *tls.Config) { // Make all necessary changes to the TLS configuration here. //} // As soon as server is initialized but not run yet, this function will be called. // If you need to modify a config, store server instance to stop it individually later, this is the place. // This function can be called multiple times, depending on the number of serving schemes. // scheme value will be set accordingly: "http", "https" or "unix" //func configureServer(s *http.Server, scheme, addr string) { //} // The middleware configuration is for the handler executors. These do not apply to the swagger.json document. // The middleware executes after routing but before authentication, binding and validation func setupMiddlewares(handler http.Handler) http.Handler { return handler } // The middleware configuration happens before anything, this middleware also applies to serving the swagger.json document. // So this is a good place to plug in a panic handling middleware, logging and metrics func setupGlobalMiddleware(handler http.Handler) http.Handler { return handler }