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

protoc-gen-openapiv2: Support map in query parameters #3238

Closed
Ja7ad opened this issue Mar 12, 2023 · 10 comments · Fixed by #3323
Closed

protoc-gen-openapiv2: Support map in query parameters #3238

Ja7ad opened this issue Mar 12, 2023 · 10 comments · Fixed by #3323

Comments

@Ja7ad
Copy link

Ja7ad commented Mar 12, 2023

the following result proto in swagger have problem with proto map in GET method as request.

https://swagger.io/docs/specification/data-models/data-types/#object

syntax = "proto3";

package rpx;
option go_package = "./abcd";
import "google/api/annotations.proto";

service Foo {
  // Sends a greeting
  rpc Bar (BarRequest) returns (BarResponse) {
    option (google.api.http) = {
      get: "/list"
    };
  }
}

message BarRequest {
  map<string, string> filters = 3;
}

message BarResponse {
}

Maps should be represented as objects in request.

Screenshot from 2023-03-12 10-24-06

{
  "swagger": "2.0",
  "info": {
    "title": "test.proto",
    "version": "version not set"
  },
  "tags": [
    {
      "name": "Foo"
    }
  ],
  "consumes": [
    "application/json"
  ],
  "produces": [
    "application/json"
  ],
  "paths": {
    "/list": {
      "get": {
        "summary": "Sends a greeting",
        "operationId": "Foo_Bar",
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "$ref": "#/definitions/rpxBarResponse"
            }
          },
          "default": {
            "description": "An unexpected error response.",
            "schema": {
              "$ref": "#/definitions/rpcStatus"
            }
          }
        },
        "tags": [
          "Foo"
        ]
      }
    }
  },
  "definitions": {
    "protobufAny": {
      "type": "object",
      "properties": {
        "@type": {
          "type": "string"
        }
      },
      "additionalProperties": {}
    },
    "rpcStatus": {
      "type": "object",
      "properties": {
        "code": {
          "type": "integer",
          "format": "int32"
        },
        "message": {
          "type": "string"
        },
        "details": {
          "type": "array",
          "items": {
            "type": "object",
            "$ref": "#/definitions/protobufAny"
          }
        }
      }
    },
    "rpxBarResponse": {
      "type": "object"
    }
  }
}
@Ja7ad
Copy link
Author

Ja7ad commented Mar 12, 2023

This is correct in OA3 :

Screenshot from 2023-03-12 10-30-44

openapi: 3.0.1
info:
  title: test.proto
  version: version not set
servers:
- url: /
tags:
- name: Foo
paths:
  /list:
    get:
      tags:
      - Foo
      summary: Sends a greeting
      operationId: Foo_Bar
      parameters:
      - name: filter
        in: query
        schema:
          type: object
          format: string
      responses:
        200:
          description: A successful response.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/rpxBarResponse'
        default:
          description: An unexpected error response.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/rpcStatus'
components:
  schemas:
    protobufAny:
      type: object
      properties:
        '@type':
          type: string
      additionalProperties:
        type: object
    rpcStatus:
      type: object
      properties:
        code:
          type: integer
          format: int32
        message:
          type: string
        details:
          type: array
          items:
            $ref: '#/components/schemas/protobufAny'
    rpxBarResponse:
      type: object

@johanbrandhorst
Copy link
Collaborator

Hi, thanks for your issue!

Note firstly that we do not support OpenAPIv3, only OpenAPIv2. It might still support specifying objects as strings in query parameters, but I'm a little curious exactly what format it uses. Is it a JSON literal? It is a bit gross to pass information like that, but theoretically you could support this today by using a string type and doing the parsing server side.

Nevertheless, this does seem like a fair feature request. The logic for doing this translation is here (I think):

if schema.Type == "object" {
return nil, nil // TODO: currently, mapping object in query parameter is not supported
}
. We'll want to change this logic to actually populate some information for the object type.

Note that the gRPC-Gateway query parameter parser itself happily handles maps, but the format is probably not the one that OpenAPI3 uses:

"map_value[key]": {"value"},
"map_value[second]": {"bar"},
"map_value[third]": {"zzz"},
"map_value[fourth]": {""},
`map_value[~!@#$%^&*()]`: {"value"},
"map_value2[key]": {"-2"},
"map_value3[-2]": {"value"},
"map_value4[key]": {"-1"},
"map_value5[-1]": {"value"},
"map_value6[key]": {"3"},
"map_value7[3]": {"value"},
"map_value8[key]": {"4"},
"map_value9[4]": {"value"},
"map_value10[key]": {"1.5"},
"map_value11[1.5]": {"value"},
"map_value12[key]": {"2.5"},
"map_value13[2.5]": {"value"},
"map_value14[key]": {"true"},
"map_value15[true]": {"value"},
. In order to be compatible with our own gateway, this is the format we'll need to generate for the OpenAPIv2 spec.

Are you interested in contributing this feature?

@johanbrandhorst johanbrandhorst changed the title Support map in GET method in swagger protoc-gen-openapiv2: Support map in query parameters Mar 14, 2023
@Ja7ad
Copy link
Author

Ja7ad commented Mar 14, 2023

Hi, thanks for your issue!

Note firstly that we do not support OpenAPIv3, only OpenAPIv2. It might still support specifying objects as strings in query parameters, but I'm a little curious exactly what format it uses. Is it a JSON literal? It is a bit gross to pass information like that, but theoretically you could support this today by using a string type and doing the parsing server side.

Nevertheless, this does seem like a fair feature request. The logic for doing this translation is here (I think):

if schema.Type == "object" {
return nil, nil // TODO: currently, mapping object in query parameter is not supported
}
. We'll want to change this logic to actually populate some information for the object type.

Note that the gRPC-Gateway query parameter parser itself happily handles maps, but the format is probably not the one that OpenAPI3 uses:

"map_value[key]": {"value"},
"map_value[second]": {"bar"},
"map_value[third]": {"zzz"},
"map_value[fourth]": {""},
`map_value[~!@#$%^&*()]`: {"value"},
"map_value2[key]": {"-2"},
"map_value3[-2]": {"value"},
"map_value4[key]": {"-1"},
"map_value5[-1]": {"value"},
"map_value6[key]": {"3"},
"map_value7[3]": {"value"},
"map_value8[key]": {"4"},
"map_value9[4]": {"value"},
"map_value10[key]": {"1.5"},
"map_value11[1.5]": {"value"},
"map_value12[key]": {"2.5"},
"map_value13[2.5]": {"value"},
"map_value14[key]": {"true"},
"map_value15[true]": {"value"},
. In order to be compatible with our own gateway, this is the format we'll need to generate for the OpenAPIv2 spec.

Are you interested in contributing this feature?

Yes, I am.

Swagger 2.0 does not support object as query parameter :(

more than one value provided for key \"{\\\"type\\\":\\\"1\\\"}\" in map \"components.list.v1.PaginatedListRequest.filters\"

I think we need switch to OpenAPI 3.1

@li31727
Copy link
Contributor

li31727 commented Apr 14, 2023

您好,感谢您的问题!

首先请注意,我们不支持 OpenAPIv3,仅支持 OpenAPIv2。它可能仍然支持在查询参数中将对象指定为字符串,但我有点好奇它使用的是什么格式。它是 JSON 文字吗?像这样传递信息有点粗暴,但理论上您现在可以通过使用类型string并在服务器端进行解析来支持这一点。

尽管如此,这看起来确实是一个公平的功能请求。做这个翻译的逻辑在这里(我认为):

if schema.Type == "object" {
return nil, nil // TODO: currently, mapping object in query parameter is not supported
}

. 我们将要更改此逻辑以实际填充对象类型的一些信息。
请注意,gRPC-Gateway 查询参数解析器本身可以愉快地处理映射,但格式可能不是 OpenAPI3 使用的格式:

"map_value[key]": {"value"},
"map_value[second]": {"bar"},
"map_value[third]": {"zzz"},
"map_value[fourth]": {""},
`map_value[~!@#$%^&*()]`: {"value"},
"map_value2[key]": {"-2"},
"map_value3[-2]": {"value"},
"map_value4[key]": {"-1"},
"map_value5[-1]": {"value"},
"map_value6[key]": {"3"},
"map_value7[3]": {"value"},
"map_value8[key]": {"4"},
"map_value9[4]": {"value"},
"map_value10[key]": {"1.5"},
"map_value11[1.5]": {"value"},
"map_value12[key]": {"2.5"},
"map_value13[2.5]": {"value"},
"map_value14[key]": {"true"},
"map_value15[true]": {"value"},

. 为了与我们自己的网关兼容,这是我们需要为 OpenAPIv2 规范生成的格式。
你有兴趣贡献这个功能吗?

Hi, thanks for your issue!

Note firstly that we do not support OpenAPIv3, only OpenAPIv2. It might still support specifying objects as strings in query parameters, but I'm a little curious exactly what format it uses. Is it a JSON literal? It is a bit gross to pass information like that, but theoretically you could support this today by using a string type and doing the parsing server side.

Nevertheless, this does seem like a fair feature request. The logic for doing this translation is here (I think):

if schema.Type == "object" {
return nil, nil // TODO: currently, mapping object in query parameter is not supported
}

. We'll want to change this logic to actually populate some information for the object type.
Note that the gRPC-Gateway query parameter parser itself happily handles maps, but the format is probably not the one that OpenAPI3 uses:

"map_value[key]": {"value"},
"map_value[second]": {"bar"},
"map_value[third]": {"zzz"},
"map_value[fourth]": {""},
`map_value[~!@#$%^&*()]`: {"value"},
"map_value2[key]": {"-2"},
"map_value3[-2]": {"value"},
"map_value4[key]": {"-1"},
"map_value5[-1]": {"value"},
"map_value6[key]": {"3"},
"map_value7[3]": {"value"},
"map_value8[key]": {"4"},
"map_value9[4]": {"value"},
"map_value10[key]": {"1.5"},
"map_value11[1.5]": {"value"},
"map_value12[key]": {"2.5"},
"map_value13[2.5]": {"value"},
"map_value14[key]": {"true"},
"map_value15[true]": {"value"},

. In order to be compatible with our own gateway, this is the format we'll need to generate for the OpenAPIv2 spec.
Are you interested in contributing this feature?

I have two question

  • In which form should the map type in the requested parameters be expressed? map_name[key]?
    It may not be easy to describe, the following is the performance of this problem as I understand it

image

  • I think if we generate request parameters of map type we need to add a description here to remind users that this is a map type and add an example in the description

@li31727
Copy link
Contributor

li31727 commented Apr 17, 2023

@johanbrandhorst

@johanbrandhorst
Copy link
Collaborator

The format is as can be seen in the tests: map_name[key_name]=value in the query parameters. It'd be great if we could auto generate a little example, good idea!

As a side note please don't @ me directly like this, it is rude.

@grpc-ecosystem grpc-ecosystem deleted a comment from li31727 Apr 18, 2023
@li31727
Copy link
Contributor

li31727 commented Apr 18, 2023

The format is as can be seen in the tests: map_name[key_name]=value in the query parameters. It'd be great if we could auto generate a little example, good idea!

As a side note please don't @ me directly like this, it is rude.

First of all I am very sorry for direct @you and I promise this will never happen again in any open source project.
Second, I am happy to provide PR to support the request parameters of the map type

@Ja7ad

This comment was marked as off-topic.

@li31727

This comment was marked as off-topic.

@johanbrandhorst
Copy link
Collaborator

Please feel free to work on adding generated example if none is provided, to make it easier to use.

li31727 added a commit to li31727/grpc-gateway that referenced this issue Apr 19, 2023
li31727 added a commit to li31727/grpc-gateway that referenced this issue Apr 19, 2023
li31727 added a commit to li31727/grpc-gateway that referenced this issue Apr 19, 2023
li31727 added a commit to li31727/grpc-gateway that referenced this issue Apr 19, 2023
li31727 added a commit to li31727/grpc-gateway that referenced this issue Apr 19, 2023
li31727 added a commit to li31727/grpc-gateway that referenced this issue Apr 19, 2023
li31727 added a commit to li31727/grpc-gateway that referenced this issue Apr 19, 2023
li31727 added a commit to li31727/grpc-gateway that referenced this issue Apr 19, 2023
li31727 added a commit to li31727/grpc-gateway that referenced this issue May 25, 2023
li31727 added a commit to li31727/grpc-gateway that referenced this issue May 25, 2023
li31727 added a commit to li31727/grpc-gateway that referenced this issue May 30, 2023
li31727 added a commit to li31727/grpc-gateway that referenced this issue May 30, 2023
li31727 added a commit to li31727/grpc-gateway that referenced this issue May 31, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants