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