英文:
Confusion creating swagger.json file from proto file
问题
我已经创建了一个包含所有必要消息和RPC函数的proto文件,用于生成REST webservice。使用protoc-gen-swagger插件,我成功将proto文件编译成swagger.json文件,一切看起来都很好,但有两个问题我无法解决。
-
swagger.json文件中的所有定义都带有我的proto文件包的前缀。有没有办法去掉这个前缀?
-
我的消息中的所有字段都是"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"
}
}
}
}
}
-
注意proto文件中的
MyMessage
和MyResponse
被翻译为json文件中的mypackageMyMessage
和mypackageMyResponse
。 -
如果我想要
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.
-
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?
-
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"
}
}
}
}
}
-
Notice how
MyMessage
andMyResponse
in the proto file translates tomypackageMyMessage
andmypackageMyResponse
in the json file. -
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
以下是要翻译的内容:
发布在这里,供其他遇到同样问题的人参考。
更新
这是代码定义如何创建定义的地方。
这是如何将字段标记为必需的方法 - 在消息定义中添加自定义选项:
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.
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论