Skip to content

Cleaner Swagger-generated schema names (omitting prefixes) #877

Closed
@jgiles

Description

This issue resurrects some of the discussion in #525, and seeks a resolution to the problem of "ugly" prefixing without violating the principle of least surprise.

For the first time, we're planning to use grpc-gateway and its generated Swagger definitions to generate a public-facing API rather than an internal API. This means the "cosmetic" concern of prefixes we do not control on the generated Swagger schema names takes on new importance.

I've hacked together a bit of code that does "minimal" package prefixing as needed, but I think the conclusion in #525 is correct - more magic here is undesirable.

Short Term

In the short term, it would be great fix the simple common case where only messages from one proto package are rendered into the Swagger doc.

The current uniquification code here

func resolveFullyQualifiedNameToSwaggerNames(messages []string) map[string]string {
is called on a bunch of fully-qualified proto names which do not actually get rendered into Swagger. In a build for my proto service with one endpoint, this is the list of names uniquified:

[]string{".google.protobuf.SourceCodeInfo.Location", ".grpc.gateway.protoc_gen_swagger.options.Operation.ResponsesEntry", ".google.protobuf.OneofDescriptorProto", ".google.protobuf.FileOptions", ".google.protobuf.Any", ".google.protobuf.DescriptorProto.ExtensionRange", ".google.protobuf.DescriptorProto.ReservedRange", ".google.protobuf.FieldDescriptorProto", ".google.protobuf.EnumDescriptorProto.EnumReservedRange", ".grpc.gateway.protoc_gen_swagger.options.Contact", ".grpc.gateway.protoc_gen_swagger.options.SecurityRequirement.SecurityRequirementValue", ".google.protobuf.FileDescriptorProto", ".google.protobuf.FieldOptions", ".google.protobuf.ServiceOptions", ".google.protobuf.GeneratedCodeInfo.Annotation", ".grpc.gateway.protoc_gen_swagger.options.Swagger.ResponsesEntry", ".grpc.gateway.protoc_gen_swagger.options.Info", ".grpc.gateway.protoc_gen_swagger.options.Schema", ".grpc.gateway.protoc_gen_swagger.options.SecurityDefinitions.SecurityEntry", ".grpc.gateway.protoc_gen_swagger.options.SecurityScheme", ".grpc.gateway.protoc_gen_swagger.options.SecurityRequirement.SecurityRequirementEntry", ".google.api.CustomHttpPattern", ".google.protobuf.ExtensionRangeOptions", ".google.protobuf.OneofOptions", ".google.protobuf.GeneratedCodeInfo", ".grpc.gateway.protoc_gen_swagger.options.Swagger", ".grpc.gateway.protoc_gen_swagger.options.ExternalDocumentation", ".grpc.gateway.protoc_gen_swagger.options.Tag", ".grpc.gateway.protoc_gen_swagger.options.SecurityRequirement", ".google.protobuf.EnumOptions", ".grpc.gateway.protoc_gen_swagger.options.Operation", ".grpc.gateway.protoc_gen_swagger.options.Response", ".grpc.gateway.protoc_gen_swagger.options.JSONSchema", ".paxos.pax.apiv0.GetBalanceResponse", ".google.api.Http", ".google.protobuf.FileDescriptorSet", ".google.protobuf.DescriptorProto", ".google.protobuf.EnumDescriptorProto", ".google.protobuf.MethodDescriptorProto", ".google.protobuf.MessageOptions", ".google.protobuf.SourceCodeInfo", ".grpc.gateway.protoc_gen_swagger.options.Scopes", ".google.api.HttpRule", ".google.protobuf.EnumValueDescriptorProto", ".google.protobuf.ServiceDescriptorProto", ".google.protobuf.EnumValueOptions", ".google.protobuf.MethodOptions", ".google.protobuf.UninterpretedOption", ".google.protobuf.UninterpretedOption.NamePart", ".grpc.gateway.protoc_gen_swagger.options.SecurityDefinitions", ".grpc.gateway.protoc_gen_swagger.options.Scopes.ScopeEntry", ".paxos.pax.apiv0.GetBalanceRequest", ".google.protobuf.FieldDescriptorProto.Label", ".google.protobuf.FieldOptions.CType", ".google.protobuf.MethodOptions.IdempotencyLevel", ".grpc.gateway.protoc_gen_swagger.options.SecurityScheme.Flow", ".google.protobuf.FieldDescriptorProto.Type", ".google.protobuf.FileOptions.OptimizeMode", ".google.protobuf.FieldOptions.JSType", ".grpc.gateway.protoc_gen_swagger.options.Swagger.SwaggerScheme", ".grpc.gateway.protoc_gen_swagger.options.JSONSchema.JSONSchemaSimpleTypes", ".grpc.gateway.protoc_gen_swagger.options.SecurityScheme.Type", ".grpc.gateway.protoc_gen_swagger.options.SecurityScheme.In"}

Only ".paxos.pax.apiv0.GetBalanceResponse" is actually rendered into Swagger.

In cases like this where only one package's messages (plus well-known types) are rendered into Swagger, we should drop the prefix (probably, by running the same uniquification code on the smaller list of rendered types).

Longer Term: Control Instead of Magic

It would be great to augment https://github.com/grpc-ecosystem/grpc-gateway/blob/master/protoc-gen-swagger/options/openapiv2.proto so that users could explicitly declare prefixes on the packages they import. Then, rather than trying to automatically avoid conflicts, protoc-gen-swagger could check for conflicts, report them as errors, and prompt the user to disambiguate manually with a human-friendly prefix.

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions