Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OpenAPI Generator : Ordering #28509

Closed
bcluap opened this issue Oct 11, 2022 · 3 comments
Closed

OpenAPI Generator : Ordering #28509

bcluap opened this issue Oct 11, 2022 · 3 comments

Comments

@bcluap
Copy link

bcluap commented Oct 11, 2022

Description

Our request is best explained by example. Here is our openapi definition in swagger as served by Quarkus:

https://eclipse-java-sandbox.ukheshe.rocks/eclipse-conductor/docs/#/

And the same openapi in readme.com (A very popular developer portal software)

https://developer.ukheshe.com/reference/

Our problem is that readme orders the API tags in the order they find them under the paths section (a,z,b etc), while swagger orders them in the order they are found in the tags section (a,b,c etc).

I believe swagger is correct and the defacto, but readme refuse to align with what swagger does, and hence our API docs tags are all out of order. We have given up asking readme and have come to ask if Quarkus/Smallrye can make a change (possibly configurable) to allow all readme.com users to order their API's the same way as Swagger.

The request is that the openapi json should not only have the tags section in alphabetical order, but then also order the paths in the order of their tags.

Implementation ideas

Loop through the tags in alphabetical order and add each path that falls under that tag. Then finally add all paths that have no tag. This way as readme loops through the paths it will populate its list of tags in alphabetical order.

@quarkus-bot
Copy link

quarkus-bot bot commented Oct 11, 2022

@MikeEdgar
Copy link
Contributor

@bcluap , I think you should be able to do this easily with an OASFilter like below. The idea here is that the filter will re-order the path items based on the first tag it finds for the operations beneath the path. You'll need to make it a little more sophisticated if a path may have a different tag depending on the HTTP method.

public class OASModelFilter implements OASFilter {

    @Override
    public void filterOpenAPI(OpenAPI openAPI) {
        List<String> tagNames = openAPI.getTags().stream().map(Tag::getName).collect(Collectors.toList());

        Map<String, PathItem> pathItems = openAPI.getPaths()
                .getPathItems()
                .entrySet()
                .stream()
                .sorted((i1, i2) -> {
                    int v1 = getTagPosition(tagNames, i1.getValue());
                    int v2 = getTagPosition(tagNames, i2.getValue());
                    return Integer.compare(v1, v2);
                })
                .collect(Collectors.toMap(Entry::getKey, Entry::getValue, (v1, v2) -> v1, LinkedHashMap::new));

        openAPI.getPaths().setPathItems(pathItems);
    }

    int getTagPosition(List<String> tagNames, PathItem pathItem) {
        return pathItem.getOperations()
                .values()
                .stream()
                .map(Operation::getTags)
                .flatMap(Collection::stream)
                .map(tagNames::indexOf)
                .findFirst()
                .orElse(-1);
    }

}

@bcluap
Copy link
Author

bcluap commented Oct 11, 2022

Ah this is brilliant. Thank you. Works a charm:
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants