swagger-parser icon indicating copy to clipboard operation
swagger-parser copied to clipboard

v3 parser does not always consider extensions

Open theangrydev opened this issue 7 years ago • 6 comments

OpenAPIV3Parser currently only takes extensions into account when the OpenAPI read methods are used.

It should also consider extensions in e.g. the SwaggerParseResult readContents method.

theangrydev avatar Aug 12 '18 20:08 theangrydev

Hi!, can you please provide a sample, or PR with a test to help us check that?. Thanks!

gracekarina avatar Aug 13 '18 22:08 gracekarina

@theangrydev can you explain a little more about the issue ?.

r-sreesaran avatar Nov 01 '18 06:11 r-sreesaran

Hi @theangrydev,

Please use the OpenAPIParser.java which considers the extension for readContents and readLocation method.

Thanks, Mohammed Rizwan

ymohdriz avatar Nov 01 '18 06:11 ymohdriz

@r-sreesaran @ymohdriz @gracekarina please see below for my current workaround that should demonstrate what is lacking from the current OpenAPIV3Parser. I do not have a PR ready, I am not familiar enough with the project to know the best way to solve this in the general case. My workaround is enough for my use case.

I use swagger-compat-spec-parser, swagger-parser-v2-converter and swagger-parser-v3 and as far as I remember, if I do not use my workaround then parsing fails for e.g. Swagger 2.0 specs with attribute openapi is missing since the readContents method of the parser does not take into account the compatibility extensions (or any extensions for that matter) properly.

class OpenApiParser {

    private final ParserWithPublicExtensionLoading parser = new ParserWithPublicExtensionLoading();

    public SwaggerParseResult readContentsFixed(String yaml) {
        ParseOptions resolve = new ParseOptions();
        resolve.setResolve(true);
        List<SwaggerParserExtension> parserExtensions = parser.getExtensions();
        List<String> allMessages = new ArrayList<>();
        for (SwaggerParserExtension extension : parserExtensions) {
            String extensionName = extension.getClass().getSimpleName();

            SwaggerParseResult parsed = extension.readContents(yaml, null, resolve);
            OpenAPI openAPI = parsed.getOpenAPI();
            if (openAPI != null) {
                return parsed;
            } else {
                parsed.getMessages().stream()
                        .map(message -> extensionName + ": " + message)
                        .forEachOrdered(allMessages::add);
            }
        }
        SwaggerParseResult errorResult = new SwaggerParseResult();
        errorResult.setMessages(allMessages);
        return errorResult;
    }

    private static class ParserWithPublicExtensionLoading extends OpenAPIV3Parser {
        @Override
        public List<SwaggerParserExtension> getExtensions() {
            return super.getExtensions();
        }
    }
}

theangrydev avatar Nov 11 '18 18:11 theangrydev

Hi @theangrydev,

readContents() method in OpenAPIParser.java considers the extensions and it's better to use this method. I believe OpenAPIParser.java is a general one to consider both the open api as well as swagger whereas OpenAPIV3Parser is specific for open api.

Can you please share your perspective on why it's required in OpenAPIV3Parser when it's available in OpenAPIParser?

@gracekarina Is there any specific reason that read() method is added in OpenAPIV3Parser instead of OpenAPIParser?

Thanks, Mohammed

ymohdriz avatar Nov 30 '18 06:11 ymohdriz

Can the parser add tests to ensure that extensions are read in all extendible locations? It looks like in v2.1.2 component extensions are being dropped.

spacether avatar Sep 14 '22 16:09 spacether