Fixed embedded spec; correctly resolve external references of embedded spec in the runtime #320
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Intro
A feature that I added last summer (the --import-mapping option) was not complete, because it breaks the embedded spec feature, thus many users can not use the advantage of request validation based on openapi spec for echo.
This pull request contains the proposal of how this could be fixed.
Solution
To solve this issue we need to embed the original spec inside the golang package. This was already implemented before, but now in go 1.16 it can be done in a single line using a go directive
//go:embed <path_to_file>
. The only downside of this approach is that we need to store the embedded file in the same package (or in child packages), otherwise go compiler will fail. I think it should be easy to implement.Next, to resolve all external references, we need to have an abstract file system, which knows about all direct and transitive external references. A function
func PathToRawSpec(pathPrefix string) map[string]func() []byte {
does this. It returns to a caller a map of all dependencies by asking a map of dependencies from direct dependencies and merging them in single map. This function is generated.Basically this is it. By calling
GetSwagger
function you will receive a valid openapi spec container with properly resolved external references. But of course all external references need to be the pre-existing golang packages.In my case I have multiple openapi specs which are served by the same web server. This is why the swagger containers which I get from
GetSwagger
function need to be merged together. I found out that for request validator it is enough to merge just paths. So I added a helper function for this. https://github.com/dududko/oapi-codegen/blob/embed-spec/pkg/util/merge.go#L36-L59Example
Here is the example of how to enable the request validation in the source code of your project.