google / gnostic

A compiler for APIs described by the OpenAPI Specification with plugins for code generation and other API support tasks.
Apache License 2.0
2.03k stars 241 forks source link

protoc-gen-openapi: Select the correct schemas that correspond to the messages used #414

Open zaakn opened 7 months ago

zaakn commented 7 months ago

fixes #392

Before fixing this issue, if fq_schema_naming = false and there were duplicates of schema names traversed and formatted from all imported proto files, the wrong message could be selected, even if it was not actually used.

Now, when a message of fully-qualified schema named foo.Contact is going to be generatd, at the same time, a duplicate short schema like Contact formatted from bar.Contact is found (used), so the fully-qualified foo.Contact will be used.


sample:

# bar.proto
syntax = "proto3";

package bar;

option go_package = "example.com/pkg/barpb";

import "google/api/annotations.proto";
import "foo.proto";

message GetBookReqest {
    string id = 1;
}

message Book {
    string id = 1;
    string name = 2;
    string shelf = 3;
}

service Library {
    rpc GetBook(GetBookReqest) returns (Book) {
        option (google.api.http) = {
            get: "/book/bar"
        };
    }
    rpc GetFooBook(GetBookReqest) returns (foo.Book) {
        option (google.api.http) = {
            get: "/book/foo"
        };
    }
}
# foo.proto
syntax = "proto3";

package foo;

option go_package = "example.com/pkg/foopb";

message Book {
    string id = 1;
    string name = 2;
    string publisher = 3;
}

protoc arguments: --openapi_opt naming=proto,fq_schema_naming=false,default_response=false

Before: ```yaml # ellipsis ... paths: /book/bar: get: # ellipsis ... responses: "200": description: OK content: application/json: schema: $ref: '#/components/schemas/Book' /book/foo: get: # ellipsis ... responses: "200": description: OK content: application/json: schema: $ref: '#/components/schemas/Book' components: schemas: Book: type: object properties: id: type: string name: type: string publisher: type: string ```

After:

# ellipsis ...
paths:
    /book/bar:
        get:
            # ellipsis ...
            responses:
                "200":
                    description: OK
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/Book'
    /book/foo:
        get:
            # ellipsis ...
            responses:
                "200":
                    description: OK
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/foo.Book'
components:
    schemas:
        Book:
            type: object
            properties:
                id:
                    type: string
                name:
                    type: string
                shelf:
                    type: string
        foo.Book:
            type: object
            properties:
                id:
                    type: string
                name:
                    type: string
                publisher:
                    type: string