influxdata / pbjson

Auto-generate serde implementations for prost types
MIT License
89 stars 43 forks source link

Question: How to generate correct response type #91

Closed EiffelFly closed 1 year ago

EiffelFly commented 1 year ago

I think this is not a bug. I may do something wrong around pb_json to make my response become str not int as expected.

How to replicate

I had reproduced a repo for showcasing the problem I am facing https://github.com/EiffelFly/axum-tonic-string-response.

The protobuf is very simple

syntax = "proto3";
package helloworld;

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloResponse) {}
}

message HelloRequest {}

message HelloResponse {
  int64 timestamp = 3;
}

This is how I generate the types https://github.com/neoeinstein/protoc-gen-prost (Under the hood it is using pbjson)

version: v1
plugins:
  - name: prost
    out: src/gen
    opt:
      - compile_well_known_types
      - extern_path=.google.protobuf=::pbjson_types
      - file_descriptor_set
      - retain_enum_prefix
  - name: prost-serde
    out: src/gen
    opt:
      - retain_enum_prefix
      - preserve_proto_field_names
  - name: tonic
    out: src/gen
    opt:
      - compile_well_known_types
      - extern_path=.google.protobuf=::pbjson_types
  - name: prost-crate
    out: src/gen
    strategy: all
    opt:
      - no_features

And here is the rest_handler

use crate::pb; // protobuf types

pub async fn greeter_handler(
    Json(data): Json<pb::helloworld::HelloRequest>,
) -> Result<impl IntoResponse, Response> {
    let resp = pb::helloworld::HelloResponse { timestamp: 123 };
    Ok((StatusCode::OK, Json(resp)))
}

What I expected response will be int but the response I get are both str

// rest response
{
  timestamp: "123",
}

// grpc response
{
  timestamp: "123",
}

Could you shed the light of this issue? I am thinking is there has some sort of flag I didn't setup correctly?

tustvold commented 1 year ago

JSON cannot store 64-bit integers, instead only storing double-precision floats (which have a maximum integral precision of 52-bits). As such the specification states to encode 64-bit integers as strings. Decode will work from both representations, double and string, but encode is supposed to only be to string.

EiffelFly commented 1 year ago

WOW, thanks you so much for sharing this information. I didn't notice this at all!

I will close this issue!