Repository: go-swagger/go-swagger
Pull request #2281 (2020-04-27 13:10:03)

Allow passing struct tags from command line
**Overview**

As discussed in #1495: allow passing a list of struct tags for model generation from the command line. This allows for instance

```bash
swagger generate server --struct-tags json --struct-tags db
```

resulting in

```go
type SomeData struct {
    SomeField string `json:"someField" db:"someField"`
}
```

When not provided, `--struct-tags` defaults to `json`, which is the current behavior.

**Implementation**

I don't really like that the property `StructTags` exists on so many types now. I tried a couple of different approaches but couldn't find a way to reliably inject server configuration into the template generation, except for the current one. Please let me know if there is a better way :+1:

**Testing**

I added one small test case to verify that the property `StructTags` is taken into account when generating the templates. I also verified that none of the examples was impacted. Please let me know if I should test more.

---

Update: I had to move the default behavior all the way to the template in order to not break any intermediate interfaces. Any existing function call along the chain should still generate `json` tags only.

Also added a small template helper function and corresponding tests.

codecov[bot]: # [Codecov](https://codecov.io/gh/go-swagger/go-swagger/pull/2281?src=pr&el=h1) Report
> Merging [#2281](https://codecov.io/gh/go-swagger/go-swagger/pull/2281?src=pr&el=desc) into [master](https://codecov.io/gh/go-swagger/go-swagger/commit/6d70865307a8f780378dbec23ec53f2d5dd841ee&el=desc) will **increase** coverage by `0.00%`.
> The diff coverage is `75.00%`.

[![Impacted file tree graph](https://codecov.io/gh/go-swagger/go-swagger/pull/2281/graphs/tree.svg?width=650&height=150&src=pr&token=aQS1DepR8C)](https://codecov.io/gh/go-swagger/go-swagger/pull/2281?src=pr&el=tree)

```diff
@@           Coverage Diff           @@
##           master    #2281   +/-   ##
=======================================
  Coverage   81.28%   81.29%           
=======================================
  Files          50       50           
  Lines        8431     8445   +14     
=======================================
+ Hits         6853     6865   +12     
- Misses       1081     1082    +1     
- Partials      497      498    +1     
```


| [Impacted Files](https://codecov.io/gh/go-swagger/go-swagger/pull/2281?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [cmd/swagger/commands/generate/model.go](https://codecov.io/gh/go-swagger/go-swagger/pull/2281/diff?src=pr&el=tree#diff-Y21kL3N3YWdnZXIvY29tbWFuZHMvZ2VuZXJhdGUvbW9kZWwuZ28=) | `100.00% <ø> (ø)` | |
| [generator/shared.go](https://codecov.io/gh/go-swagger/go-swagger/pull/2281/diff?src=pr&el=tree#diff-Z2VuZXJhdG9yL3NoYXJlZC5nbw==) | `88.52% <ø> (ø)` | |
| [generator/structs.go](https://codecov.io/gh/go-swagger/go-swagger/pull/2281/diff?src=pr&el=tree#diff-Z2VuZXJhdG9yL3N0cnVjdHMuZ28=) | `77.67% <ø> (ø)` | |
| [generator/template\_repo.go](https://codecov.io/gh/go-swagger/go-swagger/pull/2281/diff?src=pr&el=tree#diff-Z2VuZXJhdG9yL3RlbXBsYXRlX3JlcG8uZ28=) | `93.61% <60.00%> (-0.45%)` | :arrow_down: |
| [generator/model.go](https://codecov.io/gh/go-swagger/go-swagger/pull/2281/diff?src=pr&el=tree#diff-Z2VuZXJhdG9yL21vZGVsLmdv) | `84.90% <100.00%> (+0.04%)` | :arrow_up: |
| [generator/operation.go](https://codecov.io/gh/go-swagger/go-swagger/pull/2281/diff?src=pr&el=tree#diff-Z2VuZXJhdG9yL29wZXJhdGlvbi5nbw==) | `93.52% <100.00%> (+<0.01%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/go-swagger/go-swagger/pull/2281?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/go-swagger/go-swagger/pull/2281?src=pr&el=footer). Last update [6d70865...c2328d7](https://codecov.io/gh/go-swagger/go-swagger/pull/2281?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/cmd/swagger/commands/generate/model.go b/cmd/swagger/commands/generate/model.go
index 0b1f2a98..dc6a0c8e 100644
--- a/cmd/swagger/commands/generate/model.go
+++ b/cmd/swagger/commands/generate/model.go
@@ -28,6 +28,7 @@ type modelOptions struct {
 	StrictAdditionalProperties bool     `long:"strict-additional-properties" description:"disallow extra properties when additionalProperties is set to false"`
 	KeepSpecOrder              bool     `long:"keep-spec-order" description:"keep schema properties order identical to spec file"`
 	AllDefinitions             bool     `long:"all-definitions" description:"generate all model definitions regardless of usage in operations"`
+	StructTags                 []string `long:"struct-tags" description:"the struct tags to generate, repeat for multiple (defaults to json)"`
 }
 
 func (mo modelOptions) apply(opts *generator.GenOpts) {
diff --git a/docs/generate/server.md b/docs/generate/server.md
index 6fb133f6..f2e61847 100644
--- a/docs/generate/server.md
+++ b/docs/generate/server.md
@@ -64,6 +64,7 @@ Help Options:
           --existing-models=                                                      use pre-generated models e.g. github.com/foobar/model
           --strict-additional-properties                                          disallow extra properties when additionalProperties is set to false
           --keep-spec-order                                                       keep schema properties order identical to spec file
+          --struct-tags                                                           specify custom struct tags for third-party libraries, repeat for multiple (defaults to json)
 
     Options for operation generation:
       -O, --operation=                                                            specify an operation to include, repeat for multiple (defaults to all)
diff --git a/generator/bindata.go b/generator/bindata.go
index 134437fe..b69134c6 100644
--- a/generator/bindata.go
+++ b/generator/bindata.go
@@ -6,7 +6,7 @@
 // templates/client/response.gotmpl (6.273kB)
 // templates/contrib/stratoscale/client/client.gotmpl (3.591kB)
 // templates/contrib/stratoscale/client/facade.gotmpl (2.078kB)
-// templates/contrib/stratoscale/server/configureapi.gotmpl (5.874kB)
+// templates/contrib/stratoscale/server/configureapi.gotmpl (5.947kB)
 // templates/contrib/stratoscale/server/server.gotmpl (236B)
 // templates/docstring.gotmpl (270B)
 // templates/header.gotmpl (432B)
@@ -34,7 +34,7 @@
 // templates/server/responses.gotmpl (11.271kB)
 // templates/server/server.gotmpl (23.049kB)
 // templates/server/urlbuilder.gotmpl (7.641kB)
-// templates/structfield.gotmpl (1.56kB)
+// templates/structfield.gotmpl (1.91kB)
 // templates/swagger_json_embed.gotmpl (759B)
 // templates/validation/customformat.gotmpl (473B)
 // templates/validation/primitive.gotmpl (2.225kB)
@@ -58,7 +58,7 @@ import (
 func bindataRead(data []byte, name string) ([]byte, error) {
 	gz, err := gzip.NewReader(bytes.NewBuffer(data))
 	if err != nil {
-		return nil, fmt.Errorf("read %q: %w", name, err)
+		return nil, fmt.Errorf("read %q: %v", name, err)
 	}
 
 	var buf bytes.Buffer
@@ -66,7 +66,7 @@ func bindataRead(data []byte, name string) ([]byte, error) {
 	clErr := gz.Close()
 
 	if err != nil {
-		return nil, fmt.Errorf("read %q: %w", name, err)
+		return nil, fmt.Errorf("read %q: %v", name, err)
 	}
 	if clErr != nil {
 		return nil, err
@@ -227,7 +227,7 @@ func templatesContribStratoscaleClientFacadeGotmpl() (*asset, error) {
 	return a, nil
 }
 
-var _templatesContribStratoscaleServerConfigureapiGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x58\x5f\x6f\xe3\xb8\x11\x7f\xb6\x3e\xc5\x54\x68\x01\x29\x70\x64\xa0\x8f\x57\xf8\xc1\xdd\xdc\xf5\xdc\xeb\x25\xc6\x26\xe8\x3d\x14\x45\xc1\x50\x63\x99\x8d\x4c\x6a\x49\x2a\x89\xd7\xd0\x77\x2f\x86\x7f\x6c\xda\xb1\x37\x5e\xa4\x05\xba\x0f\x1b\x53\x1c\x92\xbf\xf9\xcd\x5f\x72\x32\x81\x4f\xaa\x46\x68\x50\xa2\x66\x16\x6b\x78\xdc\x40\xa3\xae\xcd\x0b\x6b\x1a\xd4\x7f\x82\x9b\x3b\xb8\xbd\x7b\x80\x1f\x6f\xe6\x0f\x55\x96\x65\xdb\x2d\x88\x25\x54\x9f\x54\xb7\xd1\xa2\x59\x59\xb8\x1e\x86\xc9\x04\xb6\x5b\xe0\x6a\xbd\x46\x69\x8f\xe6\xb6\x5b\x40\x59\xc3\x30\x64\x59\xd6\x31\xfe\xc4\x1a\x24\xe1\x6a\xb6\x98\x2f\xc2\x90\xe6\xc4\xba\x53\xda\x42\x91\x8d\x72\xae\xa4\xc5\x57\x9b\xd3\x4f\xbd\xe9\xac\x9a\xd8\xd6\xd0\x48\xa2\x9d\xac\xac\xed\xe8\x77\xab\x1a\xfa\xb3\x5c\xdb\x3c\xcb\x46\x79\x23\xec\xaa\x7f\xac\xb8\x5a\x4f\x1a\x75\xad\x3a\x94\xac\x13\x13\xd4\x5a\x69\xb7\xf4\xf4\x7c\xab\x58\xfd\x8d\x69\xdd\x4b\x2b\xd6\xf8\xae\xc0\x64\x2d\xea\xba\xc5\x17\xa6\x2f\x90\x35\xc8\x7b\x2d\xec\x26\xcf\x32\x20\x22\xbc\xe2\x06\xaa\x1b\x5c\xb2\xbe\xb5\xf3\x30\x1e\x86\xa3\xf9\x64\xa2\x24\x2b\xfc\x3e\xb2\xf9\xc3\x14\xaa\x94\x4a\xbb\xe9\x10\x02\x89\xbf\xe0\x06\x8c\xd5\x42\x36\x59\xc6\x95\x34\x16\x66\xbd\x5d\xd1\xd7\x44\x60\x0a\x39\x7d\xcd\x9d\x71\x35\x93\x0d\x42\x75\xd7\x91\x37\x08\x25\xff\xa2\x55\xdf\x19\xb2\x64\x36\x99\x34\xea\x87\xe8\x27\xb0\x56\xfc\x09\xf5\x06\xae\x25\x5b\x3b\x93\x76\xcc\x70\xd6\x8a\xaf\x08\xd5\x2d\x5b\xe3\x30\xcc\x16\x73\xb8\x16\xb2\x7b\x6a\xb2\xcc\xbb\xc8\x91\x08\x78\x19\x72\x87\x1b\x34\x5c\x8b\x8e\x4e\x24\x25\x9c\x0e\x67\x17\x08\x69\x51\x2f\x19\x47\xd8\x9e\x82\xec\xd1\x8e\x82\xa7\xa6\x3b\xbb\xef\xe7\xa0\x80\x30\xa7\xa0\x8c\x82\x07\xc7\x3d\xdf\x2e\x2c\xb8\x7d\x8d\x7c\x56\x9f\xfc\xdf\x31\x74\x4c\xb3\x35\xed\x18\x8d\x33\x0c\xd5\xc9\xe5\x0b\x27\x58\xc2\xde\x8b\xaa\xcf\x68\x3a\x25\x6b\xd4\x59\x72\xf8\x90\x25\xb1\xe4\xc2\x56\x2e\x45\x43\xa8\xb9\xfb\xd5\x7b\xed\x61\xa9\x34\xfc\xcc\x64\xdd\xa2\xf6\x3c\x06\x41\x63\x75\xcf\x2d\x6c\x9d\x16\xdf\x30\xf3\x69\x25\x67\x8b\xf9\x21\x15\x7f\x53\x94\x1f\x60\xd9\x4b\x5e\x78\x17\x1b\x43\x55\x55\x3b\xdb\x6c\x87\xd2\x71\x3d\x97\x12\xf5\xaf\x3b\xdd\x08\x2f\x21\xb4\x2b\x84\x95\x47\x09\xf8\x8a\xbc\xb7\x4a\x9b\x0a\x1e\x56\x68\x10\x6a\x05\x52\x59\x60\x5d\xd7\x6e\xc0\x2a\x27\x1c\x12\x52\xf5\x6f\xa3\x24\xd4\x8a\xf7\x94\x6c\x2a\x77\xc4\xc3\x0a\x13\xf6\xc2\x76\x68\x80\x2d\x2d\x6a\xd0\xaa\xb7\x42\x36\xf0\xd8\x5b\x78\xc4\xa5\xd2\x08\xac\xb7\x2b\x94\x56\x70\xa7\xfb\x18\x1e\x85\xac\x49\x84\xc9\x1a\x9e\x59\x2b\x6a\xf7\x3d\x1b\x1d\x63\x77\xca\x52\x0a\xaa\x02\xc1\x25\xa4\xa3\xcc\xa1\xa1\x58\x52\x5a\x7c\x45\x4d\xba\xf6\x06\x6b\x52\x81\xc5\xaf\xc0\x40\xe3\x97\x1e\x8d\x0d\xf8\x48\x39\x5a\xe3\x76\x77\x16\x7c\x61\x06\x38\x6b\x5b\xac\xa1\x37\x84\x8b\x44\x5c\x8c\x5e\xe5\x3b\x29\xe3\x0e\x23\xc4\x34\xdb\x69\x21\xb9\xe8\x58\xeb\x16\x1b\xab\x34\xd6\x20\xa4\x9b\x0b\xae\x19\x87\x79\x48\x01\xf9\x6e\xe2\x99\xb5\x3d\x56\xd9\x28\x41\xee\x34\xbd\x72\xca\x7d\xf6\x68\x4b\x70\xe9\x34\x4b\xdd\xe7\x3e\x24\xb3\x1b\x5c\x0a\x29\xde\xc6\xde\xdc\xfc\x99\x19\xc1\x9d\x76\x31\xf6\x68\x70\xe8\x61\xf3\x1b\x8a\x3e\x72\x8a\x47\x92\x3e\xb2\x8e\x87\x75\x72\x05\x61\xec\x0d\x6a\x88\xfe\xd7\x31\x63\xc2\xa0\x84\x22\x71\xc5\xb1\x07\x5f\xbe\x89\x66\x8f\x72\xb6\x98\xff\x82\x9b\x8b\x60\xce\xba\xae\x15\x68\xe0\x65\x85\x81\x4e\xca\x19\x21\x48\x72\x97\x40\xee\x55\xaf\x79\xcc\x28\x06\xed\x3b\x1a\x58\xf5\x84\xf2\x32\xd4\x07\xa0\xef\x68\xd7\x3f\xbe\x0b\xf8\x27\xa5\x21\x88\x7e\x17\xb1\x29\xac\x31\x18\xae\x3a\x34\xf0\x8f\x7f\x7e\x17\xbb\xfb\xd4\x45\x09\x2b\x44\x09\x68\xb4\xbd\x96\x06\x98\x3c\x88\x1e\x68\xc4\x73\xe0\x34\x26\x86\x83\xc4\x46\x5b\xcc\x2d\xac\x55\x2f\xad\x01\xd6\xb6\x4e\xf4\x91\x22\x04\x8d\x81\x56\x35\x82\x53\xb9\x6c\x91\x32\x03\x6a\x13\x1d\xde\xf7\x22\x21\x0d\x54\x19\x69\x17\xb1\x14\x3c\x64\xc7\x12\x0e\xe2\x3a\x6a\x44\xd9\x72\x35\x86\x7f\xb9\x31\x55\xda\x30\x3f\x5b\xcc\x0b\x5e\x66\x23\xaf\x0a\xac\xdc\xfc\xa1\x9a\x54\xa8\x3e\xa0\x69\x0c\x6c\xae\xb4\xf6\xd5\x80\x12\xc1\xd5\x99\xca\x25\x8d\x65\x92\x63\xf5\xbf\xe0\xc8\xe9\x7a\x8e\xa6\xab\xf7\xeb\xdb\x6c\x31\x4f\xe9\x34\x1d\xf2\x1d\x9d\xae\x03\xab\x66\x92\xb5\x9b\xaf\x58\x17\x21\xc7\x53\x03\x59\xdc\xfb\xdf\x7f\xbd\xbf\xbb\x2d\xc7\x90\xe7\x65\x36\x12\x4b\xb7\xee\x77\x53\x90\xa2\xa5\xbd\x22\xff\x52\xb4\x63\xff\xdf\x72\x6d\xab\x1f\xe9\xac\x65\x91\x33\xbf\x6d\xac\x1c\x3f\xc0\x1f\x9e\x73\x77\x72\x99\x8d\x86\x6c\xc4\x3a\x41\x10\x0e\x14\xb8\xc5\x97\x73\x3a\x14\x04\xbc\x74\xcb\xaa\x7b\xd4\xcf\xe8\x8e\x81\xa9\x57\xcd\x24\xdf\xbc\x4c\xa8\x8f\x53\xe0\xe1\xe7\x41\xe6\xfc\xa4\xa4\xe9\xd7\x78\x94\x2e\xa3\x61\xd8\xbe\x5b\xa1\xad\x4e\x42\x0a\x3b\xd0\x09\x94\x74\x8e\xd6\xc6\x00\x6c\x8d\x6b\x0a\x2f\xda\x26\xb4\xa8\x11\x9b\xfe\x89\xd2\x80\xcb\x05\x1a\x84\xaa\x3e\x23\xab\xc9\xe4\x96\xe9\x06\x2d\xa4\x85\xde\x73\x90\x5a\x24\x90\x72\xab\xec\x0e\x18\xd6\x45\xbe\xdd\x86\xde\x90\x1c\xde\x9f\xbb\x62\xc6\x15\xfb\x0d\x52\x79\x46\x99\xb8\x67\x4d\x46\x1f\xce\xa7\x95\x84\xcf\x85\x56\x75\xcf\x3f\xc2\x67\xd8\xe1\x02\x3e\x2f\xde\x27\x12\x1a\x3f\xed\x09\x7d\x21\x42\x7f\xd3\xc2\x12\xa1\x35\xb3\xec\xa3\x74\x76\xf1\xd4\x0f\xd0\xf9\xa1\xca\xfe\x96\x0f\x57\x4b\x9c\xc0\xf4\xdd\x52\xbd\xdd\x8a\xa5\x83\x5d\x00\x7e\x21\x6b\xc6\x6e\x26\x4f\x78\xc9\xa1\x1c\x86\xab\x5d\x29\xa4\xc0\x8d\x72\xc3\x90\xa4\x18\x08\xff\xc4\x12\x78\x75\xae\xc6\x4d\x63\x12\x81\xe4\x5f\x60\x3b\xcf\x5d\x36\xd9\x4d\x0d\x7b\x43\x9c\xdd\xd0\x69\xe7\xd5\xf2\xe9\xe5\xa2\x46\xe3\x02\xd6\x8e\xda\x83\xff\x2a\x53\xa3\xcb\x69\x1a\x1d\x71\xe4\x60\x79\x9a\x46\x17\x73\xe4\x16\x1d\xd0\x73\xb6\xa3\xf9\x4e\x66\x4e\x75\x28\xff\x5f\x4e\x95\x10\xf6\x5d\x7e\x15\xd6\x79\xf5\x4e\xba\xd6\x41\xfc\x12\x93\x67\x83\x97\x48\x9d\x2d\xe6\x49\x9f\x3f\xdd\x5f\x4c\x74\xe1\x41\xf8\x41\x79\x36\x35\x1c\xdf\xb3\xbd\xa5\x88\x6a\xdc\x3f\x44\xc4\xd7\x09\x62\x34\x51\x69\xb1\xff\x8a\xb2\x76\xaf\x43\x6f\x33\x68\xec\x92\xa6\x8e\xa8\xed\xf6\x7a\xb7\x6e\xd6\x0a\x66\xe0\x5c\xa3\x11\xd6\xed\xb3\xec\x9b\x2b\xb8\x5b\xff\xed\x7b\xb8\xd3\x64\xcf\x43\x4d\x4e\xb0\xbf\x5c\x25\x8e\x13\x34\x38\x7d\x6f\x77\xb9\x9b\xdb\x57\x6a\x30\x3c\x8a\xea\xe7\x87\x87\x45\xb8\x4a\xc5\x47\x82\xa2\xcc\x46\xd1\x66\xfb\x13\x3d\xab\x6e\xf5\xd4\xdf\xe4\x68\xae\xe0\xf6\x35\x41\x12\x56\xee\xdc\x60\xef\x47\xa7\xf9\x9e\x2d\xe6\x87\x33\xbe\x6e\x84\x5d\xfd\x0b\xc4\x9b\xe2\x90\x34\x3b\xfa\x7e\xd5\xdb\x5a\xbd\xc8\x18\x7c\x25\x6c\x9d\x03\x87\x73\x77\x82\x05\xaf\x8e\x6e\xcd\xe5\x98\x66\xbd\xe7\xfb\x0e\x39\x69\xf3\x80\xab\x8e\xae\x53\xc9\x0d\x1f\xdc\x0d\xdf\x2a\xe8\x34\x3e\xa3\xb4\xbe\x3e\x6a\x46\xd5\x5d\xc8\x58\x54\x7d\x8b\x9a\x36\x8c\x4a\x8b\xc6\xad\xad\x3e\xb3\x97\x5f\xd1\x18\xd6\x60\x79\xfc\x81\x0c\xc3\xc9\x2a\x6b\xf6\x84\xc5\xd1\xe4\x18\x5a\x94\x6e\x9f\xb2\xcc\x46\x9c\x36\xe5\x63\x70\xe3\x9d\xa2\x3c\xe8\xc0\x0e\x6e\xf9\x0c\x56\xd8\x76\xe1\xde\xec\x1a\x06\xab\xf6\x95\xd7\x77\xd8\xa1\x19\x48\x9f\x07\xa2\x37\x55\xfe\xa1\x86\x5d\x74\xff\x76\x8a\x17\x2c\x91\x2e\xf7\x6f\x0e\x85\xc6\x2f\x70\xb0\xee\x8c\xfb\x26\x4d\x86\x58\x02\x4b\x12\x7d\xd2\x54\xbb\x6c\x13\xdc\x78\xef\x89\x1a\xbf\xec\x3d\xf8\xd0\x27\xa3\x37\x38\x99\xdf\x84\x5d\x45\x39\x6e\x5f\xcb\x92\xa8\xf3\x66\x4b\xbd\xfa\xc4\xd3\xd9\x69\xc0\x47\x72\x84\x35\x1a\x25\xcc\xd0\x89\x7f\x67\x6d\x8f\xde\xaf\xc3\x43\xc7\x01\xc4\x21\xfb\x4f\x00\x00\x00\xff\xff\x96\x0d\xf0\x21\xf2\x16\x00\x00")
+var _templatesContribStratoscaleServerConfigureapiGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x58\x5f\x6f\xe3\xb8\x11\x7f\xb6\x3e\xc5\x54\x68\x01\x29\x70\x64\xa0\x8f\x57\xf8\xc1\xdd\xdc\xf5\xdc\xeb\x25\xc6\x26\xe8\x3d\x14\x45\xc1\x50\x63\x99\x8d\x4c\x6a\x49\x2a\x89\xd7\xd0\x77\x2f\x86\x7f\x6c\xda\xb1\x37\x5e\xa4\x05\xba\x0f\x1b\x4b\x9c\x21\x7f\xf3\x9b\xbf\xd4\x64\x02\x9f\x54\x8d\xd0\xa0\x44\xcd\x2c\xd6\xf0\xb8\x81\x46\x5d\x9b\x17\xd6\x34\xa8\xff\x04\x37\x77\x70\x7b\xf7\x00\x3f\xde\xcc\x1f\xaa\x2c\xcb\xb6\x5b\x10\x4b\xa8\x3e\xa9\x6e\xa3\x45\xb3\xb2\x70\x3d\x0c\x93\x09\x6c\xb7\xc0\xd5\x7a\x8d\xd2\x1e\xad\x6d\xb7\x80\xb2\x86\x61\xc8\xb2\xac\x63\xfc\x89\x35\x48\xc2\xd5\x6c\x31\x5f\x84\x47\x5a\x13\xeb\x4e\x69\x0b\x45\x36\xca\xb9\x92\x16\x5f\x6d\x4e\x3f\xf5\xa6\xb3\x6a\x62\x5b\x43\x4f\x12\xed\x64\x65\x6d\x47\xbf\x5b\xd5\xd0\x9f\xe5\xda\xe6\x59\x36\xca\x1b\x61\x57\xfd\x63\xc5\xd5\x7a\xd2\xa8\x6b\xd5\xa1\x64\x9d\x98\xa0\xd6\x4a\x3b\xd5\xd3\xeb\xad\x62\xf5\x37\x96\x75\x2f\xad\x58\xe3\xbb\x02\x93\xb5\xa8\xeb\x16\x5f\x98\xbe\x40\xd6\x20\xef\xb5\xb0\x9b\x3c\xcb\x80\x88\xf0\x86\x1b\xa8\x6e\x70\xc9\xfa\xd6\xce\xc3\xf3\x30\x1c\xad\x27\x0b\x25\x79\xe1\xf7\x91\xcd\x1f\xa6\x50\xa5\x54\xda\x4d\x87\x10\x48\xfc\x05\x37\x60\xac\x16\xb2\xc9\x32\xae\xa4\xb1\x30\xeb\xed\x8a\xde\x26\x02\x53\xc8\xe9\x6d\xee\x9c\xab\x99\x6c\x10\xaa\xbb\x8e\xa2\x41\x28\xf9\x17\xad\xfa\xce\x90\x27\xb3\xc9\xa4\x51\x3f\xc4\x38\x81\xb5\xe2\x4f\xa8\x37\x70\x2d\xd9\xda\xb9\xb4\x63\x86\xb3\x56\x7c\x45\xa8\x6e\xd9\x1a\x87\x61\xb6\x98\xc3\xb5\x90\xdd\x53\x93\x65\x93\xab\x13\x22\xe0\x65\x28\x1c\x6e\xd0\x70\x2d\x3a\x3a\x11\x86\x01\xae\x26\xde\x8c\xb3\x3a\x42\x5a\xd4\x4b\xc6\x11\xb6\xa7\x50\x7b\xc0\xa3\x10\xac\xf7\xfd\x7a\xcd\x08\x2a\xbd\x3b\x87\xc4\xc1\x88\x92\x1e\x02\xe9\x63\x6b\xd0\x6d\x92\x22\x7c\x7f\xa3\xb7\xf6\x8c\x42\x26\x44\x60\x6f\x15\x0b\x6e\x5f\xa3\x5f\xaa\x4f\xfe\xef\x18\x3a\xa6\xd9\xda\xc0\x76\x1b\x9d\x3c\x0c\xd5\x49\xf5\x85\x13\x2c\x61\x1f\x8d\xd5\x67\x34\x9d\x92\x35\x6a\xe7\xda\x78\xfa\x90\x25\x49\xe9\xf2\x5f\x2e\x45\x03\xc2\xd0\xe1\x4b\xd1\xf4\x9e\x43\x58\x2a\x0d\x3f\x33\x59\xb7\xa8\xbd\x37\x82\xa0\xb1\xba\xe7\x16\xb6\xce\x8c\x6f\xc4\xcb\x69\x2b\x67\x8b\xf9\x21\x17\x7f\x53\x54\x68\x60\xd9\x4b\x5e\xf8\x58\x1d\x43\x55\x55\x3b\x0f\x6f\x87\x32\x1b\x4d\x26\x30\x97\x12\xf5\xaf\x3b\xe3\x08\x2f\x21\xb4\x2b\x84\x95\x47\x09\xf8\x8a\xbc\xb7\x4a\x9b\x0a\x1e\x56\x68\x10\x6a\x05\x52\x59\x60\x5d\xd7\x6e\xc0\x2a\x27\x1c\x2a\x5b\xf5\x6f\xa3\x24\xd4\x8a\xf7\x54\xb5\x2a\x77\xc4\xc3\x0a\x13\xfa\xc2\x76\x68\x80\x2d\x2d\x6a\xd0\xaa\xb7\x42\x36\xf0\xd8\x5b\x78\xc4\xa5\xd2\x08\xac\xb7\x2b\x94\x56\x70\x67\xfb\x18\x1e\x85\xac\x49\x84\xc9\x1a\x9e\x59\x2b\x6a\xf7\x3e\x1b\x1d\x63\x77\xc6\x52\x2d\xab\x02\xc1\x25\xa4\x4f\x99\x43\x43\x49\xa9\xb4\xf8\x8a\x9a\x6c\xed\x0d\xd6\x64\x02\x8b\x6f\x81\x81\xc6\x2f\x3d\x1a\x1b\xf0\x91\x71\xa4\xe3\x76\x77\x1e\x7c\x61\x06\x38\x6b\x5b\xac\xa1\x37\x84\x8b\x44\x5c\xb2\x5f\xe5\x3b\x29\xe3\x0e\x23\xc4\xb4\xda\x69\x21\xb9\xe8\x58\xeb\x94\x8d\x55\x1a\x6b\x10\xd2\xad\x85\xd8\x8c\x8f\x79\xa8\x25\xf9\x6e\xe1\x99\xb5\x3d\x56\xd9\x28\x41\xee\x2c\xbd\x72\xc6\x7d\xf6\x68\x4b\x70\x75\x39\x4b\xc3\xe7\x3e\x54\xc5\x1b\x5c\x0a\x29\xde\x66\xf0\xdc\xfc\x99\x19\xc1\x9d\x75\x3e\xf9\x3c\x3d\x87\x11\x36\xbf\xa1\x5c\xa3\xa0\x78\x24\xe9\x23\xef\x78\x58\x27\x35\x08\x63\x6f\x50\x43\x8c\xbf\x8e\x19\x13\x1e\x4a\x28\x92\x50\x1c\x7b\xf0\xe5\x9b\x74\xf6\x28\x67\x8b\xf9\x2f\xb8\xb9\x08\xe6\xac\xeb\x5a\x81\x06\x5e\x56\x18\xe8\xa4\xba\x11\x92\x24\xf7\xd5\x48\xf5\x9a\xbb\x92\x22\x0c\x18\xb4\xef\x58\x60\xd5\x13\xca\xcb\x50\x1f\x80\xbe\xa3\x5d\xff\xf8\x2e\xe0\x9f\x94\x86\x20\xfa\x5d\xc4\xa6\xb0\xc6\x60\xb8\xea\xd0\xc0\x3f\xfe\xf9\x5d\xec\xee\x4b\x17\x15\xac\x90\x25\xa0\xd1\xf6\x5a\x1a\x60\xf2\x20\x7b\xa0\x11\xcf\x81\xd3\x58\x18\x0e\x0a\x1b\x6d\x31\xb7\xb0\x56\xbd\xb4\x06\x58\xdb\x3a\xd1\x47\xca\x10\x34\x06\x5a\xd5\x08\x4e\x7d\xb7\x45\xaa\x0c\xa8\x4d\x0c\x78\x3f\xd4\x84\x32\x50\x65\x64\x5d\xc4\x52\xf0\x50\x1d\x4b\x38\xc8\xeb\x68\x11\x55\xcb\xd5\x18\xfe\xe5\x9e\xa9\x65\x87\xf5\xd9\x62\x5e\xf0\x32\x1b\x79\x53\x60\xe5\xd6\x0f\xcd\xa4\x76\xf7\x01\x4b\x63\x62\x73\xa5\xb5\x6f\x07\x54\x08\xae\x4e\xb7\x2e\x21\x8d\x65\x92\x63\xf5\xbf\xe0\xc8\xd9\x7a\x8e\xa6\xab\xf7\x1b\xdc\x6c\x31\x4f\xe9\x34\x1d\xf2\x1d\x9d\x6e\x94\xab\x66\x92\xb5\x9b\xaf\x58\x17\xa1\xc6\xd3\x24\x5a\xdc\xfb\xdf\x7f\xbd\xbf\xbb\x2d\xc7\x90\xe7\x65\x36\x12\x4b\xa7\xf7\xbb\x29\x48\xd1\xd2\x5e\x91\x7f\x29\xda\xb1\xff\x6f\xb9\xb6\xd5\x8f\x74\xd6\xb2\xc8\x99\xdf\x36\x76\x8e\x1f\xe0\x0f\xcf\xb9\x3b\xb9\xcc\x46\x43\x36\x62\x9d\x20\x08\x07\x06\xdc\xe2\xcb\x39\x1b\x0a\x02\x5e\x3a\xb5\xea\x1e\xf5\x33\xba\x63\x60\xea\x4d\x33\xc9\x3b\x2f\x13\xfa\xe3\x14\x78\xf8\x79\x50\x39\x3f\x29\x69\xfa\x35\x1e\x95\xcb\xe8\x18\xb6\x1f\x57\x68\xab\x93\x90\xc2\x0e\x74\x02\x15\x9d\x23\xdd\x98\x80\x34\x06\x5d\xba\x4d\x98\x75\x23\x36\xfd\x13\x95\x01\x57\x0b\x34\x08\x55\x7d\x46\x56\x93\xcb\x2d\xd3\x0d\x5a\x48\x1b\xbd\xe7\x20\xf5\x48\x20\xe5\x56\xd9\x1d\x30\xac\x8b\x7c\xbb\x0d\x43\x26\x05\xbc\x3f\x77\xc5\x8c\x6b\xf6\x1b\xa4\xf6\x8c\x32\x09\xcf\x9a\x9c\x3e\x9c\x2f\x2b\x09\x9f\x0b\xad\xea\x9e\x7f\x84\xcf\xb0\xc3\x05\x7c\x5e\xbc\x4f\x24\x34\xbe\xda\x13\xfa\x42\x84\xfe\xa6\x85\x25\x42\x6b\x66\xd9\x47\xe9\xec\xe2\xa9\x1f\xa0\xf3\x43\x9d\xfd\x2d\x1f\xae\x97\x38\x81\xe9\xbb\xad\x7a\xbb\x15\x4b\x07\xbb\x00\xfc\x42\xde\x8c\xd3\x4c\x9e\xf0\x92\x43\x39\x0c\x57\xbb\x56\x48\x89\x1b\xe5\x86\x21\x29\x31\x10\xfe\x89\x25\xf0\xea\x5c\x8f\x9b\xc6\x22\x02\xc9\xbf\xc0\x76\x9e\xbb\x6a\xb2\x5b\x1a\xf6\x8e\x38\xbb\xa1\xb3\xce\x9b\xe5\xcb\xcb\x45\x83\xc6\x05\xac\x1d\x8d\x07\xff\x55\xa6\x46\x97\xd3\x34\x3a\xe2\xc8\xc1\xf2\x34\x8d\x2e\xe6\xc8\x29\x1d\xd0\x73\x76\xa2\xf9\x4e\x66\x4e\x4d\x28\xff\x5f\x41\x95\x10\xf6\x5d\x71\x15\xf4\xbc\x79\x27\x43\xeb\x20\x7f\xdd\xc5\xf9\x5c\xf2\x12\xa9\xb3\xc5\x3c\x99\xf3\xa7\xfb\x8b\x89\x2e\x3c\x08\xff\x50\x9e\x2d\x0d\xc7\xb7\x75\xef\x29\xa2\x1a\xf7\x5f\x34\xe2\x67\x0e\x62\x34\x31\x69\xb1\x7f\x8b\xb2\x76\x9f\x99\xde\x56\xd0\x38\x25\x4d\x1d\x51\xdb\xed\xf5\x4e\x6f\xd6\x0a\x66\xe0\xdc\xa0\x11\xf4\xf6\x55\xf6\xcd\x1d\xdc\xe9\x7f\xfb\x22\xee\x2c\xd9\xf3\x50\x53\x10\xec\x2f\x57\x49\xe0\x04\x0b\x4e\x5f\xdc\x5d\xed\xe6\xf6\x95\x06\x0c\x8f\xa2\xfa\xf9\xe1\x61\x11\xae\x52\xf1\x2b\x41\x51\x66\xa3\xe8\xb3\xfd\x89\x9e\x55\xa7\x3d\xf5\x37\x39\x5a\x2b\xb8\x7d\x4d\x90\x04\xcd\x5d\x18\xec\xe3\xe8\x34\xdf\xb3\xc5\xfc\x70\xc5\xf7\x8d\xb0\xab\xff\x04\xf1\xa6\x39\x24\xc3\x8e\xbe\x5f\xf5\xb6\x56\x2f\x32\x26\x5f\x09\x5b\x17\xc0\xe1\xdc\x9d\x60\xc1\xab\xa3\x5b\x73\x39\xa6\x55\x1f\xf9\x7e\x42\x4e\xc6\x3c\xe0\xaa\xa3\xeb\x54\x72\xc3\x07\x77\xc3\xb7\x0a\x3a\x8d\xcf\x28\xad\xef\x8f\x9a\x51\x77\x17\x32\x36\x55\x3f\xa2\xa6\x03\xa3\xd2\xa2\x71\xba\xd5\x67\xf6\xf2\x2b\x1a\xc3\x1a\x2c\x8f\x5f\x90\x63\x38\x79\x65\xcd\x9e\xb0\x38\x5a\x1c\x43\x8b\xd2\xed\x53\x96\xd9\x88\xd3\xa6\x7c\x0c\xee\x79\x67\x28\x0f\x36\xb0\x83\x5b\x3e\x83\x15\xb6\x5d\xb8\x37\xbb\x81\xc1\xaa\x7d\xe7\xf5\x13\x76\x18\x06\xd2\xcf\x03\x31\x9a\x2a\xff\xa1\x86\x5d\x74\xff\x76\x86\x17\x2c\x91\x2e\xf7\xdf\x1c\x0a\x8d\x5f\xe0\x40\xef\x4c\xf8\x26\x43\x86\x58\x02\x4b\x0a\x7d\x32\x54\xbb\x6a\x13\xc2\x78\x1f\x89\x1a\xbf\xec\x23\xf8\x30\x26\x63\x34\x38\x99\xdf\x84\x5d\x45\x39\x6e\x5f\xcb\x92\xa8\xf3\x6e\x4b\xa3\xfa\xc4\xb7\xb3\xd3\x80\x8f\xe4\x08\x6b\x74\x4a\x58\xa1\x13\xff\xce\xda\x1e\x7d\x5c\x87\x0f\x1d\x07\x10\x87\xec\x3f\x01\x00\x00\xff\xff\xbf\x0a\x3b\xdd\x3b\x17\x00\x00")
 
 func templatesContribStratoscaleServerConfigureapiGotmplBytes() ([]byte, error) {
 	return bindataRead(
@@ -242,12 +242,12 @@ func templatesContribStratoscaleServerConfigureapiGotmpl() (*asset, error) {
 		return nil, err
 	}
 
-	info := bindataFileInfo{name: "templates/contrib/stratoscale/server/configureapi.gotmpl", size: 5874, mode: os.FileMode(0644), modTime: time.Unix(1482416923, 0)}
-	a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xb, 0xa4, 0xc5, 0x20, 0x91, 0x73, 0x11, 0x98, 0xd3, 0x5b, 0x5a, 0x94, 0x9f, 0x16, 0xb4, 0x60, 0xe5, 0xe5, 0xf9, 0x26, 0xb6, 0x71, 0x97, 0x83, 0x43, 0x9e, 0x97, 0xd7, 0x97, 0xf7, 0x39, 0x8f}}
+	info := bindataFileInfo{name: "templates/contrib/stratoscale/server/configureapi.gotmpl", size: 5947, mode: os.FileMode(0644), modTime: time.Unix(1482416923, 0)}
+	a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x8e, 0xfa, 0xcc, 0x2b, 0xe0, 0xd5, 0x5d, 0x37, 0x26, 0x14, 0x3e, 0xea, 0xdf, 0x91, 0x16, 0x60, 0x5f, 0xb9, 0xb2, 0xf6, 0xd7, 0xba, 0x14, 0xb3, 0x26, 0xaf, 0xf2, 0xfd, 0xbc, 0xb1, 0x99, 0xa4}}
 	return a, nil
 }
 
-var _templatesContribStratoscaleServerServerGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x5c\x8e\x31\x4e\x03\x31\x10\x45\x7b\x9f\xe2\x77\x54\x59\x1f\x80\x0a\x25\x14\x69\x48\x8a\x5c\xc0\xac\x27\xf6\x08\xef\x78\x65\x8f\xb0\x2c\xcb\x77\x47\x41\x08\x21\xca\xff\xdf\x2b\x9e\xb5\x38\x66\x4f\x08\x24\x54\x9c\x92\xc7\x7b\x47\xc8\x87\xda\x5c\x08\x54\x9e\x71\xba\xe0\xed\x72\xc3\xeb\xe9\x7c\x5b\x8c\x31\x63\x80\xef\x58\x8e\x79\xef\x85\x43\x54\x1c\xe6\xb4\x16\x63\x60\xcd\xdb\x46\xa2\xff\xd8\x18\x20\xf1\x98\xd3\x18\xb3\xbb\xf5\xc3\x05\x7a\xc8\xcb\xcb\xf5\x7c\xfd\x99\x0f\x66\x2d\x34\x72\xc5\x9d\x13\x81\x2b\x58\x94\x44\x39\x8b\x4b\xa9\x83\xb6\x5d\xfb\x82\xac\x91\x4a\xe3\x4a\x7f\x02\xd1\x38\xa5\xdf\x7a\x38\x54\x2a\x9f\xdf\xb7\xae\x11\x8d\xe0\xb3\x3c\x29\x9a\x13\x35\x5f\x01\x00\x00\xff\xff\xfd\xeb\x4b\x38\xec\x00\x00\x00")
+var _templatesContribStratoscaleServerServerGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x5c\x8e\x31\x6e\x03\x21\x10\x45\x7b\x4e\xf1\xbb\x54\x5e\x0e\x90\x2a\xb2\x53\xb8\xc9\xba\xf0\x05\xc8\xee\x18\x46\x61\x87\x15\x8c\x82\x10\xe2\xee\xd1\x4a\x51\x14\xb9\xfc\xff\xbd\xe2\x59\x8b\x73\x5a\x09\x9e\x84\xb2\x53\x5a\xf1\xd9\xe0\xd3\xa9\x54\xe7\x3d\xe5\x57\x5c\x66\x7c\xcc\x77\xbc\x5f\xae\xf7\xc9\x18\xd3\x3b\xf8\x81\xe9\x9c\xf6\x96\xd9\x07\xc5\x69\x0c\x6b\xd1\x3b\x96\xb4\x6d\x24\xfa\xc4\x7a\x07\xc9\x8a\x31\x8c\x31\xbb\x5b\xbe\x9c\xa7\x43\x9e\xde\x6e\xd7\xdb\xef\x3c\x98\xb5\xd0\xc0\x05\x0f\x8e\x04\x2e\x60\x51\x12\xe5\x24\x2e\xc6\x06\xda\x76\x6d\x13\x66\x0d\x94\x2b\x17\xfa\x17\x88\xca\x31\xfe\xd5\xc3\xa1\x50\xfe\x3e\xee\xc0\x4b\x40\x25\xac\x49\x5e\x14\xd5\x89\x9a\x9f\x00\x00\x00\xff\xff\x2d\x16\x0f\xd5\xec\x00\x00\x00")
 
 func templatesContribStratoscaleServerServerGotmplBytes() ([]byte, error) {
 	return bindataRead(
@@ -263,7 +263,7 @@ func templatesContribStratoscaleServerServerGotmpl() (*asset, error) {
 	}
 
 	info := bindataFileInfo{name: "templates/contrib/stratoscale/server/server.gotmpl", size: 236, mode: os.FileMode(0644), modTime: time.Unix(1482416923, 0)}
-	a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xa2, 0x7d, 0x4f, 0x36, 0x58, 0x28, 0x19, 0xa4, 0x74, 0xeb, 0xf1, 0xd5, 0x9e, 0xf2, 0x58, 0x68, 0x9a, 0x5a, 0xc8, 0x58, 0x99, 0x36, 0xaf, 0x14, 0xd6, 0x80, 0x71, 0xf4, 0xfc, 0x40, 0x31, 0xf1}}
+	a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xc, 0xd5, 0x5d, 0x94, 0x14, 0x1a, 0x11, 0x8d, 0xcb, 0x6b, 0xa2, 0x86, 0x57, 0x64, 0xf6, 0xea, 0xef, 0x64, 0xb9, 0x5b, 0xa4, 0x99, 0x23, 0x68, 0x3e, 0x81, 0x90, 0x35, 0x51, 0x9e, 0xff, 0xb5}}
 	return a, nil
 }
 
@@ -787,7 +787,7 @@ func templatesServerUrlbuilderGotmpl() (*asset, error) {
 	return a, nil
 }
 
-var _templatesStructfieldGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x54\x4b\x8f\xd3\x30\x10\xbe\xe7\x57\x8c\xac\x3d\x6c\x25\xe2\xbd\xef\x91\x97\x08\x82\xad\x44\x57\x88\xe3\x5a\xf6\xa4\x18\xf9\x85\xed\x20\x82\xe5\xff\x8e\x9c\xa6\x69\x83\xd2\x56\x80\x50\xb9\x7a\xe6\xcb\xf7\x98\x99\xa4\x04\x02\x5b\x69\x10\x48\x88\xbe\xe3\xb1\x95\xa8\x04\x81\x9c\x2b\x80\x94\x6a\x90\x2d\x18\x1b\xe1\x86\x36\xe1\x39\x0b\xf8\xd8\x3b\x84\x7a\xa8\x02\xdc\xdd\x41\x4a\x10\x51\x3b\xc5\x22\x02\x11\x96\x87\xe8\xa5\xd9\x12\xa0\x30\xf6\x94\x6f\x1c\x3a\x9c\xb7\x0e\x7d\xec\x3f\x32\x25\x05\x8b\xd2\x9a\x97\x96\x6f\xf6\x98\x89\x14\x8d\xc8\xb9\x4a\x09\x1c\x0b\x9c\x29\xf9\x03\x81\x3e\x30\x8d\x39\xcf\x09\x03\xff\x8c\x9a\x15\x4d\x3b\x46\x78\xfa\x12\xac\xb9\x27\xd5\xa8\xfc\x86\xbe\x61\xbf\xca\xae\x87\x22\xaa\x80\x07\x93\x74\xed\xe5\x56\x1a\xa6\x0a\xc9\xcc\x3b\x33\x02\x6e\x4b\x00\xf4\x03\x7e\xed\xa4\x47\xb1\x02\xda\x84\x57\xda\xc5\x7e\xad\x65\x8c\x28\x20\xe7\x67\x56\xcb\xa2\x2a\xf6\x29\x15\xf1\x90\x73\x4a\x05\x4e\x9b\xf0\x76\xb3\x7e\xd8\x39\x2c\x8d\xbb\x7c\xa6\xae\x6a\x74\x0b\x39\x4f\xa2\xe9\xa7\xf7\xef\x46\x1d\xf0\x5d\xab\x7b\x92\xd2\xf1\x1b\x99\x83\x0b\xe0\x45\x17\xa2\xd5\x8f\xac\x30\x94\x80\x66\x0f\x53\xfb\x53\x75\x40\x0e\xd0\xfd\xe0\x63\xe7\x14\x5e\x79\xee\x73\x53\x7f\x38\xf6\x9a\xfc\x6e\x24\xc5\x0a\x1f\x2a\x10\xd0\xcb\x81\xd3\x9f\xca\xe9\xe8\x40\x9a\x96\x71\xfc\x0f\xae\x04\x4e\x9c\xc9\xed\xea\x7c\x62\xd5\x06\xe3\x22\xee\x2c\x6a\x35\x1b\xd3\xc2\xfe\x5c\x33\x16\xb8\xbc\x45\xff\x3e\x95\xd9\xbe\x38\x2f\xbf\x2d\xff\x54\x39\xd3\x78\x4c\xf0\xba\xd4\x2f\x68\x3b\x43\xb2\x78\xc0\x7f\xc7\xf1\x33\x00\x00\xff\xff\x22\xfc\x66\xeb\x18\x06\x00\x00")
+var _templatesStructfieldGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x55\x4d\x8f\xd3\x30\x10\xbd\xe7\x57\x8c\xac\x1c\x76\xa5\x6d\x96\x73\x25\x2e\x7c\x89\x22\xd8\x4a\x64\x85\x38\xae\x65\x4f\xc2\xa0\xd8\x09\xb6\x8b\x28\x56\xfe\x3b\x72\x9c\x4f\x48\xbb\xaa\x10\x5a\x6e\x8d\x3d\x6f\xde\x9b\xe7\x67\xd7\x7b\x90\x58\x90\x46\x60\xd6\x99\x83\x70\x05\x61\x25\x19\xb4\x6d\x02\xe0\xfd\x06\xa8\x00\x5d\x3b\x48\xb3\x9d\x7d\xc1\x2d\xde\x1f\x1b\x84\x4d\xb7\x0b\x70\x7b\x0b\xde\x83\x43\xd5\x54\xdc\x21\x30\x59\x0b\xeb\x0c\xe9\x92\x41\x06\x7d\x4d\xe8\x31\x55\x34\xa6\x6e\xd0\xb8\xe3\x27\x5e\x91\xe4\x8e\x6a\xfd\xaa\x16\xf9\x80\x19\x49\x51\xcb\xb6\x4d\xbc\x87\x86\x5b\xc1\x2b\xfa\x89\x90\xdd\x71\x85\x6d\xbb\x24\xb4\xe2\x0b\x2a\x1e\x34\x45\x46\x78\xe8\x1b\xa4\x81\x08\xb6\xcf\x07\x1d\x61\xcd\x70\x5d\x22\xa4\x74\x03\x69\x1c\xf5\x9e\x97\xa1\x24\xcd\xf2\xe1\xd3\xce\x55\x53\x01\xa5\x83\x94\xe0\x19\x44\x5e\xd4\x72\x7d\xaa\xb1\x1d\x03\x49\xc2\x01\xeb\x7e\xce\x58\x58\xde\x09\x65\xbd\xae\x69\xce\xca\xe2\x25\x2d\xd9\x57\x5b\x6b\x76\xba\xdd\x20\xb0\x97\x9f\x7d\xfe\xf0\x3e\xd8\x16\xf4\xff\x50\xd5\x96\x79\x3f\x5f\x63\xf3\x99\x06\xc8\xcb\x83\x75\xb5\x0a\xa2\xe3\xd0\x8b\x85\x11\xf0\x90\x4c\xd8\x24\x40\x97\x21\xea\xc4\x8e\x6d\xb3\x08\xde\xb2\x89\x26\xcd\xde\xf2\x3f\xf3\xb4\x39\x61\x4b\x16\xe7\xcd\xf6\x86\x4a\xd2\xbc\xea\xf5\xcf\x4f\x8a\x6b\x09\x57\x21\xa8\x43\xed\x47\xfc\x76\x20\x83\xf2\x7a\x5c\xd9\xd9\xd7\xaa\x71\xc7\xbd\x22\xe7\x30\x28\xbf\xa9\x15\x05\xc7\xdd\x71\x1c\xc6\xfb\xce\x84\x11\xf1\x2e\xdf\xdf\xc5\x78\x86\xfa\x18\xee\xdf\x5d\x8b\x1f\x2c\x99\x9d\xc0\xdc\x11\x77\x68\x2a\x7c\xe2\x5b\x35\x49\x0e\xc0\x8b\x2f\x55\x48\xdd\x96\x6d\xe2\x88\x17\x84\x24\x8c\x22\xba\x1d\xb0\x68\xa8\xe3\x34\xe7\x93\xd3\x19\xb5\x2b\xb8\xc0\xff\xe0\x0d\x82\x13\x8f\xd0\xd5\xf5\x79\xc7\x92\x1c\xdd\x2a\xee\x2c\xea\x7a\x71\x4c\x2b\xf9\x79\x4a\x5b\xe0\xf1\x14\xfd\x7b\x57\x16\x79\x69\x0c\x7d\x5f\xff\xcb\x12\x5c\xe1\x9c\xe0\x4d\xd8\x7f\x44\xdb\x19\x92\xd5\x0b\xfc\x77\x1c\xbf\x02\x00\x00\xff\xff\x19\x4c\x16\x4a\x76\x07\x00\x00")
 
 func templatesStructfieldGotmplBytes() ([]byte, error) {
 	return bindataRead(
@@ -802,8 +802,8 @@ func templatesStructfieldGotmpl() (*asset, error) {
 		return nil, err
 	}
 
-	info := bindataFileInfo{name: "templates/structfield.gotmpl", size: 1560, mode: os.FileMode(0644), modTime: time.Unix(1482416923, 0)}
-	a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x48, 0x31, 0xe1, 0x1d, 0x7, 0x54, 0x18, 0x49, 0x4e, 0x66, 0xb7, 0x8a, 0x80, 0x29, 0xf6, 0x96, 0x32, 0xe2, 0x91, 0x24, 0xe, 0x3, 0xc7, 0xe9, 0xd, 0xbc, 0xf1, 0x57, 0xf5, 0x5c, 0x6b, 0xd7}}
+	info := bindataFileInfo{name: "templates/structfield.gotmpl", size: 1910, mode: os.FileMode(0644), modTime: time.Unix(1482416923, 0)}
+	a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x52, 0x92, 0x5, 0x7b, 0xfd, 0x5c, 0x15, 0xc8, 0x62, 0x64, 0x3a, 0xd1, 0xd4, 0x9, 0xca, 0xfd, 0x38, 0x1d, 0xa9, 0x4c, 0xdc, 0x5b, 0x30, 0xb9, 0x5a, 0xc6, 0xd8, 0x22, 0xa8, 0xd6, 0xb8, 0x6f}}
 	return a, nil
 }
 
diff --git a/generator/model.go b/generator/model.go
index c6f6c302..de73cffd 100644
--- a/generator/model.go
+++ b/generator/model.go
@@ -228,6 +228,7 @@ func makeGenDefinitionHierarchy(name, pkg, container string, schema spec.Schema,
 		IncludeModel:               opts.IncludeModel,
 		StrictAdditionalProperties: opts.StrictAdditionalProperties,
 		WithXML:                    opts.WithXML,
+		StructTags:                 opts.StructTags,
 	}
 	if err := pg.makeGenSchema(); err != nil {
 		return nil, fmt.Errorf("could not generate schema for %s: %v", name, err)
@@ -419,6 +420,7 @@ type schemaGenContext struct {
 	Container    string
 	Schema       spec.Schema
 	TypeResolver *typeResolver
+	StructTags   []string
 
 	GenSchema      GenSchema
 	Dependencies   []string // NOTE: Dependencies is actually set nowhere
@@ -536,7 +538,7 @@ func (sg *schemaGenContext) shallowClone() *schemaGenContext {
 	if pg.Container == "" {
 		pg.Container = sg.Name
 	}
-	pg.GenSchema = GenSchema{}
+	pg.GenSchema = GenSchema{StructTags: sg.StructTags}
 	pg.Dependencies = nil
 	pg.Named = false
 	pg.Index = 0
@@ -1309,7 +1311,7 @@ func (sg *schemaGenContext) buildAdditionalProperties() error {
 		}
 
 		hasMapNullOverride := sg.GenSchema.IsMapNullOverride
-		sg.GenSchema = GenSchema{}
+		sg.GenSchema = GenSchema{StructTags: sg.StructTags}
 		sg.Schema = *spec.RefProperty("#/definitions/" + newObj.Name)
 		if err := sg.makeGenSchema(); err != nil {
 			return err
@@ -1354,6 +1356,7 @@ func (sg *schemaGenContext) makeNewStruct(name string, schema spec.Schema) *sche
 		IncludeValidator:           sg.IncludeValidator,
 		IncludeModel:               sg.IncludeModel,
 		StrictAdditionalProperties: sg.StrictAdditionalProperties,
+		StructTags:                 sg.StructTags,
 	}
 	if schema.Ref.String() == "" {
 		pg.TypeResolver = sg.TypeResolver.NewWithModelName(name)
@@ -1853,6 +1856,7 @@ func (sg *schemaGenContext) makeGenSchema() error {
 	sg.GenSchema.IncludeModel = sg.IncludeModel
 	sg.GenSchema.StrictAdditionalProperties = sg.StrictAdditionalProperties
 	sg.GenSchema.Default = sg.Schema.Default
+	sg.GenSchema.StructTags = sg.StructTags
 
 	var err error
 	returns, err := sg.shortCircuitNamedRef()
diff --git a/generator/operation.go b/generator/operation.go
index 9adafdfa..0ea896d8 100644
--- a/generator/operation.go
+++ b/generator/operation.go
@@ -1069,6 +1069,7 @@ func (b *codeGenOpBuilder) buildOperationSchema(schemaPath, containerName, schem
 		IncludeValidator:           true,
 		StrictAdditionalProperties: b.GenOpts.StrictAdditionalProperties,
 		ExtraSchemas:               make(map[string]GenSchema),
+		StructTags:                 b.GenOpts.StructTags,
 	}
 
 	var (
diff --git a/generator/shared.go b/generator/shared.go
index 1c93fad7..b8ae3049 100644
--- a/generator/shared.go
+++ b/generator/shared.go
@@ -256,6 +256,7 @@ type GenOpts struct {
 	Operations             []string
 	Models                 []string
 	Tags                   []string
+	StructTags             []string
 	Name                   string
 	FlagStrategy           string
 	CompatibilityMode      string
diff --git a/generator/structs.go b/generator/structs.go
index 367c31fb..23660ec0 100644
--- a/generator/structs.go
+++ b/generator/structs.go
@@ -92,6 +92,7 @@ type GenSchema struct {
 	IncludeModel               bool
 	Default                    interface{}
 	WantsMarshalBinary         bool // do we generate MarshalBinary interface?
+	StructTags                 []string
 }
 
 func (g GenSchemaList) Len() int      { return len(g) }
diff --git a/generator/template_repo.go b/generator/template_repo.go
index 7a6b29d8..3b33d2e2 100644
--- a/generator/template_repo.go
+++ b/generator/template_repo.go
@@ -84,6 +84,7 @@ func DefaultFuncMap(lang *LanguageOpts) template.FuncMap {
 		"hasPrefix":        strings.HasPrefix,
 		"stringContains":   strings.Contains,
 		"imports":          lang.imports,
+		"dict":             dict,
 	})
 }
 
@@ -564,3 +565,18 @@ func prefixForName(arg string) string {
 	}
 	return "Nr"
 }
+
+func dict(values ...interface{}) (map[string]interface{}, error) {
+	if len(values)%2 != 0 {
+		return nil, fmt.Errorf("Expected even number of arguments, got %d", len(values))
+	}
+	dict := make(map[string]interface{}, len(values)/2)
+	for i := 0; i < len(values); i += 2 {
+		key, ok := values[i].(string)
+		if !ok {
+			return nil, fmt.Errorf("Expected string key, got %+v", values[i])
+		}
+		dict[key] = values[i+1]
+	}
+	return dict, nil
+}
diff --git a/generator/templates/contrib/stratoscale/server/configureapi.gotmpl b/generator/templates/contrib/stratoscale/server/configureapi.gotmpl
index 3c4a2b79..99956e86 100644
--- a/generator/templates/contrib/stratoscale/server/configureapi.gotmpl
+++ b/generator/templates/contrib/stratoscale/server/configureapi.gotmpl
@@ -31,13 +31,16 @@ const AuthKey contextKey = "Auth"
 {{ range .OperationGroups -}}
 //go:generate mockery -name {{ pascalize .Name}}API -inpkg
 
-// {{ pascalize .Name }}API {{ .Description }}
+/* {{ pascalize .Name }}API {{ .Description }} */
 type {{ pascalize .Name }}API interface {
 {{ range .Operations -}}
-	{{ if .Description -}}
-	// {{ pascalize .Name }} is {{ .Description }}
+	{{ if .Summary -}}
+	/* {{ pascalize .Name }} {{ .Summary }} */
+	{{ else if .Description -}}
+	/* {{ pascalize .Name }} {{ .Description }} */
 	{{ end -}}
 	{{ pascalize .Name }}(ctx context.Context, params {{.Package}}.{{ pascalize .Name }}Params) middleware.Responder
+
 {{ end -}}
 }
 {{ end }}
diff --git a/generator/templates/contrib/stratoscale/server/server.gotmpl b/generator/templates/contrib/stratoscale/server/server.gotmpl
index 952ad102..0330309c 100644
--- a/generator/templates/contrib/stratoscale/server/server.gotmpl
+++ b/generator/templates/contrib/stratoscale/server/server.gotmpl
@@ -6,4 +6,4 @@
 
 package {{ .APIPackage }}
 
-// this file is intentionally empty. otherwise go-swagger will generate a server witch we don't want
+// this file is intentionally empty. Otherwise go-swagger will generate a server which we don't want
diff --git a/generator/templates/structfield.gotmpl b/generator/templates/structfield.gotmpl
index 892e22ed..fd78ac08 100644
--- a/generator/templates/structfield.gotmpl
+++ b/generator/templates/structfield.gotmpl
@@ -3,17 +3,27 @@
     // {{ template "docstring" . }}
     {{- template "propertyValidationDocString" .}}
   {{- end}}
-{{ pascalize .Name}} {{ template "schemaType" . }} `json:"
-{{- if $.HasBaseType -}}
-  -
-{{- else }}
-  {{- .OriginalName }}
-  {{- if and (not .Required) .IsEmptyOmitted }},omitempty{{ end }}{{ if .IsJSONString }},string{{ end }}
-{{- end }}"
-{{- if .XMLName }} xml:"{{ .XMLName }}"{{ end }}
-{{- if .CustomTag }} {{ .CustomTag }}{{ end }}`
+{{ pascalize .Name}} {{ template "schemaType" . }} `
+  {{- $prop := . }}
+  {{- range $i, $structTag := $.StructTags }}
+    {{- if gt $i 0 }} {{ end }}
+    {{- template "structTag" dict "Tag" $structTag "Schema" $prop }}
+  {{- else }}
+    {{- template "structTag" dict "Tag" "json" "Schema" $prop }}
+  {{- end }}
+  {{- if .XMLName }} xml:"{{ .XMLName }}"{{ end }}
+  {{- if .CustomTag }} {{ .CustomTag }}{{ end }}`
 {{ end }}
 
+{{- define "structTag" }}
+  {{- .Tag }}:"
+  {{- if $.HasBaseType -}}
+    -
+  {{- else }}
+    {{- .Schema.OriginalName }}
+    {{- if and (not .Schema.Required) .Schema.IsEmptyOmitted }},omitempty{{ end }}{{ if .Schema.IsJSONString }},string{{ end }}
+  {{- end }}"
+{{- end }}
 {{- define "tuplefield" }}
   {{- if not $.IsBaseType -}}
     // {{ template "docstring" . }}


Test patch:
diff --git a/generator/model_test.go b/generator/model_test.go
index f27432fa..08161233 100644
--- a/generator/model_test.go
+++ b/generator/model_test.go
@@ -185,6 +185,7 @@ func TestGenerateModel_SchemaField(t *testing.T) {
 	gmp.MinItems = &in2
 	gmp.UniqueItems = true
 	gmp.ReadOnly = true
+	gmp.StructTags = []string{"json", "db"}
 	tt.assertRender(gmp, `// The title of the property
 //
 // The description of the property
@@ -198,7 +199,7 @@ func TestGenerateModel_SchemaField(t *testing.T) {
 // Max Items: 30
 // Min Items: 30
 // Unique: true
-`+"SomeName string `json:\"some name\" mytag:\"foobar,foobaz\"`\n")
+`+"SomeName string `json:\"some name\" db:\"some name\" mytag:\"foobar,foobaz\"`\n")
 }
 
 var schTypeGenDataSimple = []struct {
diff --git a/generator/template_repo_test.go b/generator/template_repo_test.go
index e3d91eea..4466c50d 100644
--- a/generator/template_repo_test.go
+++ b/generator/template_repo_test.go
@@ -55,6 +55,8 @@ PascalizeSpecialChar2={{ pascalize "-1" }}
 PascalizeSpecialChar3={{ pascalize "1" }}
 PascalizeSpecialChar4={{ pascalize "-" }}
 PascalizeSpecialChar5={{ pascalize "+" }}
+Dict={{ template "dictTemplate" dict "Animal" "Pony" "Shape" "round" "Furniture" "table" }}
+{{ define "dictTemplate" }}{{ .Animal }} of the {{ .Shape }} {{ .Furniture }}{{ end }}
 `
 }
 
@@ -427,6 +429,7 @@ func TestTemplates_FuncMap(t *testing.T) {
 	assert.Contains(t, rendered.String(), "PascalizeSpecialChar3=Nr1\n")
 	assert.Contains(t, rendered.String(), "PascalizeSpecialChar4=Minus\n")
 	assert.Contains(t, rendered.String(), "PascalizeSpecialChar5=Plus\n")
+	assert.Contains(t, rendered.String(), "Dict=Pony of the round table\n")
 }
 
 // AddFile() global package function (protected vs unprotected)
@@ -600,3 +603,17 @@ func TestFuncMap_AsJSON(t *testing.T) {
 		require.Error(t, err)
 	}
 }
+
+func TestFuncMap_Dict(t *testing.T) {
+	d, err := dict("a", "b", "c", "d")
+	require.NoError(t, err)
+	assert.Equal(t, map[string]interface{}{"a": "b", "c": "d"}, d)
+
+	// odd number of arguments
+	_, err = dict("a", "b", "c")
+	require.Error(t, err)
+
+	// none-string key
+	_, err = dict("a", "b", 3, "d")
+	require.Error(t, err)
+}