从proto文件创建swagger.json文件时出现混淆。

huangapple go评论119阅读模式
英文:

Confusion creating swagger.json file from proto file

问题

我已经创建了一个包含所有必要消息和RPC函数的proto文件,用于生成REST webservice。使用protoc-gen-swagger插件,我成功将proto文件编译成swagger.json文件,一切看起来都很好,但有两个问题我无法解决。

  1. swagger.json文件中的所有定义都带有我的proto文件包的前缀。有没有办法去掉这个前缀?

  2. 我的消息中的所有字段都是"optional"的。它们没有明确指定为"optional",但也没有指定为"required",根据定义,这使它们成为可选字段。Proto3不再支持required/optional/repeating,即使我使用Proto2并添加这些关键字,似乎也不会影响swagger.json的输出。我该如何在proto文件中指定一个字段是必需的,以便protoc-gen-swagger会在json输出中添加required部分?

以下是一个非常基本的proto文件示例:

webservice.proto

syntax = "proto3";
package mypackage;
import "google/api/annotations.proto";

service MyAPIWebService {
    rpc MyFunc (MyMessage) returns (MyResponse) {
        option (google.api.http) = {
            post: "/message"
            body: "*"
        };
    }
}

message MyMessage {
    string MyString = 1;
    int64 MyInt = 2;
}

message MyResponse {
    string MyString = 1;
}

使用以下命令将其编译为swagger.json文件:

protoc -I. -I"%GOPATH%/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis" --swagger_out=logtostderr=true:. webservice.proto

输出如下:

webservice.swagger.json

{
  "swagger": "2.0",
  "info": {
    "title": "webservice.proto",
    "version": "version not set"
  },
  "schemes": [
    "http",
    "https"
  ],
  "consumes": [
    "application/json"
  ],
  "produces": [
    "application/json"
  ],
  "paths": {
    "/message": {
      "post": {
        "operationId": "MyFunc",
        "responses": {
          "200": {
            "description": "",
            "schema": {
              "$ref": "#/definitions/mypackageMyResponse"
            }
          }
        },
        "parameters": [
          {
            "name": "body",
            "in": "body",
            "required": true,
            "schema": {
              "$ref": "#/definitions/mypackageMyMessage"
            }
          }
        ],
        "tags": [
          "MyAPIWebService"
        ]
      }
    }
  },
  "definitions": {
    "mypackageMyMessage": {
      "type": "object",
      "properties": {
        "MyString": {
          "type": "string"
        },
        "MyInt": {
          "type": "string",
          "format": "int64"
        }
      }
    },
    "mypackageMyResponse": {
      "type": "object",
      "properties": {
        "MyString": {
          "type": "string"
        }
      }
    }
  }
}
  1. 注意proto文件中的MyMessageMyResponse被翻译为json文件中的mypackageMyMessagemypackageMyResponse

  2. 如果我想要MyMessage:MyString是必需的,我需要在"definitions"中的"mypackageMyMessage"部分添加一个如下的段落:

"required":[
    "MyString"
]

我希望能够在proto文件中指定这一点,这样每次编译时就不必手动编辑json文件了。

英文:

I've created a proto file with all the necessary messages and rpc functions for a REST webservice I intend to generate. Using the protoc-gen-swagger plugin I've managed to compile that proto file into a swagger.json file and all seems well, except for two things, which I can't seem to work out.

  1. All the definitions in the swagger.json file has the name of my proto file's package prefixed onto them. Is there a way to get rid of this?

  2. All of the fields of my messages are "optional". They're not specified explicitly as such but they're not specified to be "required" which, by definition, makes them optional. Proto3 no longer supports required/optional/repeating but even if I use Proto2 and add those keywords, it doesn't seem to affect the swagger.json ouput. How do I specifiy in my proto file that a field is required such that protoc-gen-swagger will add the required section to the json output?

Here is a sample of a very basic proto file:

webservice.proto

syntax = "proto3";
package mypackage;
import "google/api/annotations.proto";

service MyAPIWebService {
	rpc MyFunc (MyMessage) returns (MyResponse) {
		option (google.api.http) = {
			post: "/message"
			body: "*"
		};
	}
}

message MyMessage {
	string MyString = 1;
	int64 MyInt = 2;
}

message MyResponse {
	string MyString = 1;
}

This is then compiled into a swagger.json file with the following command:

> protoc -I. -I"%GOPATH%/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis" --swagger_out=logtostderr=true:. webservice.proto

which yields the following output:
webservice.swagger.json

{
  "swagger": "2.0",
  "info": {
    "title": "webservice.proto",
    "version": "version not set"
  },
  "schemes": [
    "http",
    "https"
  ],
  "consumes": [
    "application/json"
  ],
  "produces": [
    "application/json"
  ],
  "paths": {
    "/message": {
      "post": {
        "operationId": "MyFunc",
        "responses": {
          "200": {
            "description": "",
            "schema": {
              "$ref": "#/definitions/mypackageMyResponse"
            }
          }
        },
        "parameters": [
          {
            "name": "body",
            "in": "body",
            "required": true,
            "schema": {
              "$ref": "#/definitions/mypackageMyMessage"
            }
          }
        ],
        "tags": [
          "MyAPIWebService"
        ]
      }
    }
  },
  "definitions": {
    "mypackageMyMessage": {
      "type": "object",
      "properties": {
        "MyString": {
          "type": "string"
        },
        "MyInt": {
          "type": "string",
          "format": "int64"
        }
      }
    },
    "mypackageMyResponse": {
      "type": "object",
      "properties": {
        "MyString": {
          "type": "string"
        }
      }
    }
  }
}
  1. Notice how MyMessage and MyResponse in the proto file translates to mypackageMyMessage and mypackageMyResponse in the json file.

  2. If I wanted, for instance, MyMessage:MyString to be required, I'd have to add a section to the "mypackageMyMessage" section in "definitions" that looks like this:

    "required":[
    "MyString"
    ]

I would definitely prefer if there was a way I could specify that in the proto file already so that I don't have to manually edit the json file every time I compile it.

答案1

得分: 7

以下是要翻译的内容:

发布在这里,供其他遇到同样问题的人参考。


更新
这是代码定义如何创建定义的地方。

https://github.com/grpc-ecosystem/grpc-gateway/blob/master/protoc-gen-swagger/genswagger/template.go#L859


这是如何将字段标记为必需的方法 - 在消息定义中添加自定义选项:

message MyMessage {
    option (grpc.gateway.protoc_gen_swagger.options.openapiv2_schema) = {
        json_schema: {
            title: "MyMessage"
            description: "Does something neat"
            required: ["MyString"]
        }
    };

    string MyString = 1;
    int64 MyInt = 2;
}
英文:

Posting here for anyone else who comes across this question looking for the same information.


UPDATE
This is where the code defines how definitions are created.

https://github.com/grpc-ecosystem/grpc-gateway/blob/master/protoc-gen-swagger/genswagger/template.go#L859


This is how you can denote fields as required -- add a custom option to your message definition:

message MyMessage {
    option (grpc.gateway.protoc_gen_swagger.options.openapiv2_schema) = {
        json_schema: {
            title: "MyMessage"
            description: "Does something neat"
            required: ["MyString"]
        }
    };

    string MyString = 1;
    int64 MyInt = 2;
}

答案2

得分: 1

你的前缀 mypackage 是在 .proto 文件中的命名空间的一部分。它来自于以下代码行:package mypackage; 删除这行代码并重新生成 JSON。

英文:

Your prefix mypackage is a part of namespacing in .proto file. It is coming from line: package mypackage; delete this line and regenerate json

huangapple
  • 本文由 发表于 2017年2月21日 21:08:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/42368221.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定