grpc-ecosystem / grpc-gateway

gRPC to JSON proxy generator following the gRPC HTTP spec

Home Page:https://grpc-ecosystem.github.io/grpc-gateway/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

When the body is set to a oneof field, other fields in the same group are included as query.

ovargas opened this issue Β· comments

πŸ› Bug Report

I'm using the ability to set in the body a oneof field and then create additional bindings to create endpoints for each one of them. While this works perfectly fine in the grpc gateway, the openapi documentation includes the other fields in the same oneof group as query params, which is not valid.

To Reproduce

Given a proto like

pipeline.proto

syntax = "proto3";

package sample.pipeline.v1;

option go_package = "sample/pipeline/v1;pipelinev1";

import "google/protobuf/struct.proto";
import "google/protobuf/empty.proto";
import "google/api/annotations.proto";

message ExecuteRequest {
  string pipeline_id = 1;
  oneof activity {
    string foo = 2;
    string bar = 3;
    google.protobuf.Struct baz = 4;
  }
}

service PipelineService {

  rpc Execute(ExecuteRequest) returns (google.protobuf.Empty){
    option (google.api.http) = {
      post: "/v1/pipeline/{pipeline_id}"
      body: "*"
      additional_bindings: [
        {
          post: "/v1/pipeline/{pipeline_id}/foo"
          body: "foo"
        },
        {
          post: "/v1/pipeline/{pipeline_id}/bar"
          body: "bar"
        },
        {
          post: "/v1/pipeline/{pipeline_id}/baz"
          body: "baz"
        }
      ]
    };
  };
}

buf.gen.yaml

version: v1
plugins:
- name: go
  out: ./api
  opt: paths=source_relative
- name: go-grpc
  out: ./api
  opt: paths=source_relative
- name: grpc-gateway
  out: ./api
  opt:
  - paths=source_relative
  - generate_unbound_methods=true
  - allow_repeated_fields_in_body=true
- name: openapiv2
  out: ./swagger
  opt:
    - output_format=yaml
  strategy: all

The generated yaml is:

swagger: "2.0"
info:
  title: pipeline/v1/service.proto
  version: version not set
tags:
  - name: PipelineService
consumes:
  - application/json
produces:
  - application/json
paths:
  /v1/pipeline/{pipelineId}:
    post:
      operationId: PipelineService_Execute
      responses:
        "200":
          description: A successful response.
          schema:
            type: object
            properties: {}
        default:
          description: An unexpected error response.
          schema:
            $ref: '#/definitions/rpcStatus'
      parameters:
        - name: pipelineId
          in: path
          required: true
          type: string
        - name: body
          in: body
          required: true
          schema:
            $ref: '#/definitions/PipelineServiceExecuteBody'
      tags:
        - PipelineService
  /v1/pipeline/{pipelineId}/bar:
    post:
      operationId: PipelineService_Execute3
      responses:
        "200":
          description: A successful response.
          schema:
            type: object
            properties: {}
        default:
          description: An unexpected error response.
          schema:
            $ref: '#/definitions/rpcStatus'
      parameters:
        - name: pipelineId
          in: path
          required: true
          type: string
        - name: bar
          in: body
          required: true
          schema:
            type: string
        - name: foo
          in: query
          required: false
          type: string
        - name: baz
          in: query
          required: false
          type: object
      tags:
        - PipelineService
  /v1/pipeline/{pipelineId}/baz:
    post:
      operationId: PipelineService_Execute4
      responses:
        "200":
          description: A successful response.
          schema:
            type: object
            properties: {}
        default:
          description: An unexpected error response.
          schema:
            $ref: '#/definitions/rpcStatus'
      parameters:
        - name: pipelineId
          in: path
          required: true
          type: string
        - name: baz
          in: body
          required: true
          schema:
            type: object
        - name: foo
          in: query
          required: false
          type: string
        - name: bar
          in: query
          required: false
          type: string
      tags:
        - PipelineService
  /v1/pipeline/{pipelineId}/foo:
    post:
      operationId: PipelineService_Execute2
      responses:
        "200":
          description: A successful response.
          schema:
            type: object
            properties: {}
        default:
          description: An unexpected error response.
          schema:
            $ref: '#/definitions/rpcStatus'
      parameters:
        - name: pipelineId
          in: path
          required: true
          type: string
        - name: foo
          in: body
          required: true
          schema:
            type: string
        - name: bar
          in: query
          required: false
          type: string
        - name: baz
          in: query
          required: false
          type: object
      tags:
        - PipelineService
definitions:
  PipelineServiceExecuteBody:
    type: object
    properties:
      foo:
        type: string
      bar:
        type: string
      baz:
        type: object
  protobufAny:
    type: object
    properties:
      '@type':
        type: string
    additionalProperties: {}
  protobufNullValue:
    type: string
    enum:
      - NULL_VALUE
    default: NULL_VALUE
    description: |-
      `NullValue` is a singleton enumeration to represent the null value for the
      `Value` type union.

      The JSON representation for `NullValue` is JSON `null`.

       - NULL_VALUE: Null value.
  rpcStatus:
    type: object
    properties:
      code:
        type: integer
        format: int32
      message:
        type: string
      details:
        type: array
        items:
          type: object
          $ref: '#/definitions/protobufAny'

Expected behavior

For paths ***/foo, ***/bar, ***/baz the query string reference should not include the other fields in the oneof as query params

Your Environment

macOS 14.2.1 (23C71) (Sonoma)