Newer
Older
// 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
BaseURL string
// 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
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,
)
}
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
// 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)),
}
// 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
}