Skip to content

Commit

Permalink
Strict server generation (deepmap#499)
Browse files Browse the repository at this point in the history
* Added strict server generation that does automatic marshaling of request and response bodies, meaning less manual code and forced schema compliance

* Support any content type by using io.Reader

* removed generating marshalling code from client for content types other than JSON

* Multipart and formdata are now passed as forms without any binding

* run make generate to fix the build

* added sorting of request bodies to reduce number of random changes in generated code, fixed content type in RequestBody's comment

* Implemented basic formdata binder (not yet integrated into strict server)

* Added tests for strict generation, support for form marshalling, client improvements

* Fixed incorrect referencing of request bodies, added sorting of response definitions

* Added sorting of content types in responses

* Support multipart responses using callback function, added header example

* Added sorting of headers in response objects

* Added proper testing to strict servers

* Fix after master merge

* Reuse responses defined in components section, moved strict test to tests

* When multiple responses ref to a single reusable response, only the first one will use an alias, all others will generate new structs

* Update generated code after merge

* Some documentation for strict server

* Support for AdditionalProperties when binding forms

Co-authored-by: ilya.bogdanov <ilya.bogdanov@ispringsolutions.com>
Co-authored-by: ilya.bogdanov <ilya.bogdanov@ispring.com>
  • Loading branch information
3 people committed Jun 29, 2022
1 parent 5ea78ce commit 7ba241a
Show file tree
Hide file tree
Showing 56 changed files with 7,863 additions and 62 deletions.
41 changes: 41 additions & 0 deletions README.md
Expand Up @@ -260,6 +260,47 @@ Alternatively, [Gorilla](https://github.com/gorilla/mux) is also 100% compatible

</summary></details>

#### Strict server generation

oapi-codegen also supports generating RPC inspired strict server, that will parse request bodies and encode responses.
The main points of this code is to automate some parsing, abstract user code from server specific code,
and also to force user code to comply with the schema.
It supports binding of `application/json` and `application/x-www-form-urlencoded` to a struct, for `multipart` requests
it generates a `multipart.Reader`, which can be used to either manually iterating over parts or using `runtime.BindMultipart`
function to bind the form to a struct. All other content types are represented by a `io.Reader` interface.

To form a response simply return one of the generated structs with corresponding status code and content type. For example,
to return a status code 200 JSON response for a AddPet use the `AddPet200JSONResponse` struct which will set the correct
Content-Type header, status code and will marshal the response data. You can also return an `error` interface, that will be
cause an `Internal Server Error` response. If you return a response that is not supported by this method, you will get an error.
Unfortunately go does not support union types outside generic code, so we can't type check in compile time.

Short example:
```go
type PetStoreImpl struct {}
func (*PetStoreImpl) GetPets(ctx context.Context, request GetPetsRequestObject) interface{} {
var result []Pet
// Implement me
return GetPets200JSONResponse(result)
}
```
For a complete example see `/examples/petstore-expanded/strict`.

Code is generation with a configuration flag `genrate: strict-server: true` along with any other server (echo, chi, gin and gorilla are supported).
The generated strict wrapper can then be used as an implementation for `ServerInterface`. Setup example:
```go
func SetupHandler() {
var myApi PetStoreImpl
myStrictApiHandler := api.NewStrictHandler(myApi, nil)
e := echo.New()
petstore.RegisterHandlers(e, &myStrictApiHandler)
}
```

Strict server also has its own middlewares. It can access to both request and response structs,
as well as raw request\response data. It can be used for logging the parsed request\response objects, transforming go errors into response structs,
authorization, etc. Note that middlewares are server-specific.

#### Additional Properties in type definitions

[OpenAPI Schemas](https://swagger.io/specification/#schemaObject) implicitly
Expand Down
2 changes: 2 additions & 0 deletions cmd/oapi-codegen/oapi-codegen.go
Expand Up @@ -323,6 +323,8 @@ func newConfigFromOldConfig(c oldConfiguration) configuration {
opts.Generate.GinServer = true
case "gorilla":
opts.Generate.GorillaServer = true
case "strict-server":
opts.Generate.Strict = true
case "types":
opts.Generate.Models = true
case "spec":
Expand Down
5 changes: 1 addition & 4 deletions examples/authenticated-api/echo/api/api.gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 1 addition & 4 deletions examples/petstore-expanded/chi/api/petstore.gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 1 addition & 4 deletions examples/petstore-expanded/echo/api/models/models.gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 1 addition & 4 deletions examples/petstore-expanded/gin/api/petstore-types.gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 1 addition & 4 deletions examples/petstore-expanded/gorilla/api/petstore.gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 1 addition & 4 deletions examples/petstore-expanded/petstore-client.gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 7ba241a

Please sign in to comment.