github.com/rzurga/go-swagger@v0.28.1-0.20211109195225-5d1f453ffa3a/docs/faq/faq_server.md (about) 1 <!-- Questions about server generation --> 2 ## Server generation and customization 3 4 ### What are the dependencies required by the generated server? 5 The code generation process ends with a message indicating package dependencies for your generated code. 6 7 Basically, here are the required packages: 8 - [`github.com/go-openapi/errors`](https://www.github.com/go-openapi/errors) 9 - [`github.com/go-openapi/loads`](https://www.github.com/go-openapi/loads) 10 - [`github.com/go-openapi/runtime`](https://www.github.com/go-openapi/runtime) 11 - [`github.com/go-openapi/spec`](https://www.github.com/go-openapi/spec) 12 - [`github.com/go-openapi/strfmt`](https://www.github.com/go-openapi/strfmt) 13 - [`github.com/go-openapi/swag`](https://www.github.com/go-openapi/swag) 14 - [`github.com/go-openapi/validate`](https://www.github.com/go-openapi/validate) 15 16 And depending on your generation options, a command line flags handling package: 17 - [`github.com/jessevdk/go-flags`](https://www.github.com/jessevdk/go-flags), or 18 - [`github.com/spf13/pflags`](https://www.github.com/spf13/pflags) 19 - [`flag`](flag) 20 21 This dependency used to be necessary up to release 0.14: 22 - [`github.com/tylerb/graceful`](https://www.github.com/tylerb/graceful) 23 24 These packages may of course be *vendored* with your own source. 25 26 Originally from issue [#1085](https://github.com/go-swagger/go-swagger/issues/1085). 27 28 ### How to add custom flags? 29 `go-swagger` ships with an option to select a flag management package: `swagger generate server --flag-strategy=[go-flags|pflag|flag]` 30 31 You may of course customize your server to accept arbitrary flags the way you prefer. 32 This should be normally done with the generated main.go. For customization, you may either skip the generation of the main package (`--skip-main`) 33 and provide your own, or customize template generation to generate a custom main. 34 35 Here's an example: [kv store example](https://github.com/go-openapi/kvstore/blob/master/cmd/kvstored/main.go#L50-L57) 36 37 Originally from issue [#1036](https://github.com/go-swagger/go-swagger/issues/1036). 38 39 ### How do you integrate the flag sets of go-swagger and other packages, in particular, glog? 40 _Use-case_: logger 41 >I am trying to integrate a package into a go-swagger generated API that is using the `github.com/golang/glog` logger. 42 >When I initialize the glog logger it appears to shield the flags defined in the go-swagger runtime. 43 44 **Answer**: the generated API has a Logger property that is a function with signature: `func(string, ...interface{})` 45 46 You can configure it with any logger that exposes the signature. 47 48 eg.: https://github.com/go-swagger/go-swagger/blob/master/examples/authentication/restapi/configure_auth_sample.go#L33 49 50 _Use-case_: logger flags 51 >Still having a problem with how and where to initialize glog so that both sets of flags are honored: 52 >the runtime flags, such as `--tls-certificate` and the glog flags like `-log_dir` and `-stderrthreshold`. 53 54 >If I initialize glog in the config_xxx.go I don't get the go-swagger runtime flags, and if I initialize glog in the engine, I get the error: `logging before flag.Parse`. 55 >I realize that this question is not so much about logging *per se*, but more about how to merge the flag sets defined by different packages. 56 57 **Answer**: you can generate a server with `--flag-strategy pflag` 58 59 After that you can use its integration to add goflags. You would do this in the main file. 60 Subsequently it's probably a good idea to generate code with `--exclude-main` so the update is preserved. 61 62 See also: https://github.com/spf13/pflag#supporting-go-flags-when-using-pflag 63 64 Example: 65 ```golang 66 import ( 67 goflag "flag" 68 flag "github.com/spf13/pflag" 69 ) 70 71 var ip *int = flag.Int("flagname", 1234, "help message for flagname") 72 73 func main() { 74 flag.CommandLine.AddGoFlagSet(goflag.CommandLine) 75 flag.Parse() 76 } 77 ``` 78 79 Originally from issue [#762](https://github.com/go-swagger/go-swagger/issues/762). 80 81 ### How to serve two or more swagger specs from one server? 82 _Use-case_: I want a go-swagger generated server to serve 2 swagger specs that have no overlap on paths. 83 One is a generic metadata api that is implemented by many services and the other is a 84 service-specific api. The built-in server.go template Server struct, by having exactly 85 one API & handler, appears to prevent this. 86 87 **Suggestions**: 88 1. Use go-swagger `mixin` command to merge specs into a single one 89 2. Create yourself a top-level swagger file that just includes the two lower-level ones (using `$ref`). 90 You may use go-swagger `flatten` to flatten the resulting spec 91 3. You can also make your own main function and use the code from the generation 92 of both spec (with `--skip-main`). 93 This allows for customization like using a different middleware stack, which in turn gives you 94 the ability to serve 2 swagger specs at different paths. 95 96 Originally from issue [#1005](https://github.com/go-swagger/go-swagger/issues/1005). *(comes with a sample main.go for spec composition)*. 97 98 ### How to access access API struct inside operator handler? 99 _Use-Case_: 100 my question is how can I access the generated API interface from within an operation handler function ? 101 Can i pass it somehow via context or any other way to do that? 102 103 **Answer**: **No**. It's not reachable from within the handler anywhere. 104 105 106 >I created a module like apache access module ACL based on IP address for different URLs. 107 >Instead of URL for lookup key I decided to use Operation.ID. 108 >Lookup would be faster in that way because each operation has a unique id according to swagger specification. 109 >The problem comes when I want to check against that ACL of mine... 110 111 **Suggestions**: 112 This is possible in 2 ways. 113 - first way is by using an authenticator, 114 - the second way is making a middleware (not global) 115 116 Example with Authenticator: 117 ```golang 118 // Authenticator represents an authentication strategy 119 // implementations of Authenticator know how to authenticate the 120 // request data and translate that into a valid principal object or an error 121 type Authenticator interface { 122 Authenticate(interface{}) (bool, interface{}, error) 123 } 124 ``` 125 You may see the schemes currently supported here: https://github.com/go-openapi/runtime/tree/master/security 126 127 Example with Middleware: 128 ```golang 129 // The middleware configuration is for the handler executors. These do not apply to the swagger.json document. 130 // The middleware executes after routing but before authentication, binding and validation. 131 func setupMiddlewares(handler http.Handler) http.Handler { 132 return handler 133 } 134 ``` 135 to get to the matched route in one of those you can: 136 ```golang 137 import "github.com/gorilla/context" 138 context.Get(3, request) 139 ``` 140 That gets you a matched route. 141 142 >Note: it might be worth it to expose `Context` as an exported method on the API builder. 143 >That would be a simple PR to add the following code in go-swagger 144 ```golang 145 func (o *LifecycleManagerAPI) Context() *middleware.Context { 146 if o.context == nil { 147 o.context = middleware.NewRoutableContext(o.spec, o, nil) 148 } 149 return o.context 150 } 151 ``` 152 then your middleware could take a context in and use `RouteInfo(request)` like this one: https://github.com/go-openapi/runtime/blob/master/middleware/security.go. 153 154 _Similar use-case_: 155 I have some domain objects I need access to in the handlers (db connection, telemetry client, etc). 156 157 *What is the recommended way/place to define these and access them in the handlers?* 158 159 >Would I define them in configure_xxx() and make wrapper functions for the handlers to make them accessible? 160 >Or is there a nice way to add them to the context? 161 >I was looking for some examples of this but couldn't find anything. 162 163 **Hint**: look at this one: https://github.com/go-openapi/kvstore 164 165 The important takeaway is that main and the handlers have to be pulled outside of the generated code since only configure_xxx() is protected. 166 And main() doesn't call configureAPI() ... 167 that was a little confusing looking through the other examples and not seeing any changes to the vanilla config code. 168 169 _Similar use-case_: dependency injection 170 171 Wouldn't it be better to have all the handlers automatically be part of a default struct that simply has a Context member variable or empty interface? 172 173 >That would save everyone a lot of copy/paste when we need to inject some info. 174 >I mean, a different context than the one available on params.HTTPRequest.Context(), 175 >more like an application level context, e.g. something I can stuff a database reference or other business state into. 176 177 **Hint**: remember that the generated packages are made of a series of files that you can extend and tailor to your own needs by adding more files. 178 179 For instance, a new (non generated) file in the operations package could bring to life the applicative context/dependencies injection and be called from the configure_xxx. 180 You may alternatively modify the generation by providing your own templates, and possibly extend the interface of the Server struct. 181 182 Originally from issue [#661](https://github.com/go-swagger/go-swagger/issues/661). 183 184 ### Use go-swagger to generate different client or servers 185 _Use-Case_: 186 I am using go-swagger to generate some part of a server application automatically 187 and I would love to reuse our code by transforming the code in go templates. 188 189 >It would be enough to export the `appGenerator` type and have a function that returns it (maybe generator.GenerateServer itself?). 190 >I would then use `appGenerator` to execute the templates. 191 >How could I realize this? Is it possible with go-swagger? 192 193 **Answer**: you can provide your own templates for go-swagger. 194 195 The client and server generators allow you to specify a directory on disk to add custom templates. 196 197 Here are some docs: http://goswagger.io/generate/templates/ 198 199 >In VIC they do this: https://github.com/vmware/vic/tree/master/lib/apiservers/templates 200 >https://github.com/vmware/vic/blob/master/Makefile#L274-L281 201 202 **Hint**: you can also override templates by using the same names: 203 https://github.com/go-swagger/go-swagger/blob/master/generator/templates.go#L61-L73 204 205 *Wouldn't this generate roughly the same structure of the server?* 206 207 >I don't want to change minor details, I want to have code that looks totally different 208 >(but only for the server part, models and clients are more than okay) while using code the parsing and validation from go-swagger. 209 >This means different number of files and different functionalities. 210 211 **Answer**: yes, it would generate a similar structure. 212 213 Note: customizing templates already brings many options to the table, including generating artifacts in other languages than go. 214 215 There is some documentation on the config file format here: https://github.com/go-swagger/go-swagger/blob/gen-layout-configfile/docs/use/template_layout.md 216 217 Also keep in mind that `go-openapi` and `go-swagger` constitute a _toolkit_ 218 and provide you the *tools* to adapt to your own use case. 219 The `swagger` command line and standard templates only covers general purpose use-cases. 220 221 If you think your use-case would benefit to many people, feel free to make the necessary changes for your case to work and submitting a PR. 222 223 Example config file for generation: 224 ```YAML 225 layout: 226 application: 227 - name: configure 228 source: asset:serverConfigureapi 229 target: "{{ joinFilePath .Target .ServerPackage }}" 230 file_name: "{{ .Name }}_client.go" 231 skip_exists: true 232 - name: main 233 source: asset:serverMain 234 target: "{{ joinFilePath .Target \"cmd\" (dasherize (pascalize .Name)) }}-server" 235 file_name: "main.go" 236 - name: embedded_spec 237 source: asset:swaggerJsonEmbed 238 target: "{{ joinFilePath .Target .ServerPackage }}" 239 file_name: "embedded_spec.go" 240 - name: server 241 source: asset:serverServer 242 target: "{{ joinFilePath .Target .ServerPackage }}" 243 file_name: "server.go" 244 - name: builder 245 source: asset:serverBuilder 246 target: "{{ joinFilePath .Target .ServerPackage .Package }}" 247 file_name: "{{ snakize (pascalize .Name) }}_api.go" 248 - name: doc 249 source: asset:serverDoc 250 target: "{{ joinFilePath .Target .ServerPackage }}" 251 file_name: "doc.go" 252 models: 253 - name: definition 254 source: asset:model 255 target: "{{ joinFilePath .Target .ModelPackage }}" 256 file_name: "{{ (snakize (pascalize .Name)) }}.go" 257 operations: 258 - name: parameters 259 source: asset:serverParameter 260 target: "{{ joinFilePath .Target .ServerPackage .APIPackage .Package }}" 261 file_name: "{{ (snakize (pascalize .Name)) }}_parameters.go" 262 - name: responses 263 source: asset:serverResponses 264 target: "{{ joinFilePath .Target .ServerPackage .APIPackage .Package }}" 265 file_name: "{{ (snakize (pascalize .Name)) }}_responses.go" 266 - name: handler 267 source: asset:serverOperation 268 target: "{{ joinFilePath .Target .ServerPackage .APIPackage .Package }}" 269 file_name: "{{ (snakize (pascalize .Name)) }}.go" 270 ``` 271 272 ### Support streaming responses 273 _Use-Case_: Docker client expects a stream of JSON structs from daemon to show a progress bar, as in: 274 ```bash 275 curl -i -X POST http://IP:PORT/images/create?fromImage=alpine&tag=latest 276 ``` 277 *How could I write a server providing a streaming response?* 278 279 **Answer**: Operations in the generated server are expected to return a responder. 280 281 This interface is defined as: 282 ```golang 283 // Responder is an interface for types to implement 284 // when they want to be considered for writing HTTP responses 285 type Responder interface { 286 WriteResponse(http.ResponseWriter, httpkit.Producer) 287 } 288 ``` 289 290 With the `middleware.ResponderFunc` helper construct, you can just write a `func(http.ResponseWriter, httpkit.Producer)` 291 where you want a streaming response. 292 293 This should be sufficient. However: 294 295 >I've toyed with a channel based stream where you send struct objects to a channel, which then gets streamed to the browser. 296 >I decided against this because it seemed to just add complexity for little benefit. 297 >I can be persuaded to implement such a responder though, and should somebody send a PR like that I would not say no to it. 298 299 Originally from issue [#305](https://github.com/go-swagger/go-swagger/issues/305). 300 301 ### OAuth authentication does not redirect to the authorization server 302 _Use-Case_: oauth2 accessCode flow does not redirect to the authorization server 303 304 > In my understanding, if the accessCode flow is used for oauth2 securitydefinition, the generated server could redirect the authentication to the oauth2 server, e.g., https://accounts.google.com/o/oauth2/v2/auth. However, my generated code does not perform the redirection. Could anyone help on this? Thanks. 305 306 Like in: 307 ```yaml 308 --- 309 swagger: '2.0' 310 info: 311 title: oauth2 debug 312 version: 0.3.0 313 produces: 314 - application/json 315 schemes: 316 - http 317 basePath: /api 318 securityDefinitions: 319 OauthSecurity: 320 type: oauth2 321 flow: accessCode 322 authorizationUrl: 'https://accounts.google.com/o/oauth2/v2/auth' 323 tokenUrl: 'hhttps://www.googleapis.com/oauth2/v4/token' 324 scopes: 325 admin: Admin scope 326 user: User scope 327 security: 328 - OauthSecurity: 329 - user 330 paths: 331 /customers: 332 .... 333 ``` 334 335 336 > The generated server does not redirect the browser to the google login page. 337 338 **Answer**: Redirection flow is for UI. The spec has them so your UI can do the redirection. 339 340 Swagger 2.0 only defines those properties as hints for a UI to work, 341 this doesn't have to be server side. At the same time the redirection flow is not supported in an API 342 but you can use an OAuth 2.0 middleware from any library to get you that functionality 343 344 Originally from issue [#1217](https://github.com/go-swagger/go-swagger/issues/1217). 345 346 ### HTTPS TLS Cipher Suites not supported by AWS Elastic LoadBalancer 347 348 _Use-case_: AWS Elastic LoadBalancer forwards https requests to instances, and their security policy is 'ELBSecurityPolicy-2016-08'. 349 However, while running the server on https, the server keeps on logging 350 351 `http: TLS handshake error from 192.168.X.X:XXXXX: tls: no cipher suite supported by both client and server.` 352 353 If we remove the cipher suites on the generated code, it resolves the issue - 354 355 ```golang 356 CipherSuites: []uint16{ 357 tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 358 tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 359 tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 360 tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 361 }, 362 ``` 363 364 The ELB security policy 'ELBSecurityPolicy-2016-08' does include these cipher suites, however all requests sent by the ELB are rejected by the server. 365 366 **Answer**: you can generate the server with a different compatibility mode for the older generation of ciphers 367 368 ``` 369 swagger generate server --compatibility-mode=intermediate 370 ``` 371 372 Originally from issue [#1383](https://github.com/go-swagger/go-swagger/issues/1383). 373 374 ### Which mime types are supported? 375 376 _Use-Case_: I seem to be unable to find supported mime-types that the API's can consume and produce. Any references? 377 378 **Answer**: see the current list of supported media MIMEs [here](https://github.com/go-swagger/go-swagger/blob/3099f611ada66d42974160ac4e0ec475d24b7041/generator/support.go#L279) 379 You can add more through the consumer producer mechanism. 380 381 Originally from issue [#1022](https://github.com/go-swagger/go-swagger/issues/1022). 382 383 ### Is it possible to return error to main function of server? 384 385 _Use-Case_: Is it possible to return error to main function of server? 386 387 > For example, my server saves some configs in file, and I want that if config file is missing, 388 > then server must be stopped with some error code. It is possible to do it with panic(err), 389 > but I think it is not good way. So can I return error main function of server ? 390 391 **Answer**: you can make your own main function. 392 393 There is an example here: https://github.com/go-openapi/kvstore/blob/master/cmd/kvstored/main.go 394 395 There is a command line argument to avoid overwriting the main when generating: `--exclude-main`. 396 397 Originally from issue [#1060](https://github.com/go-swagger/go-swagger/issues/1060). 398 399 ------------- 400 401 Back to [all contributions](README.md#all-contributed-questions)