-
Notifications
You must be signed in to change notification settings - Fork 508
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
JSON Mapping #75
Comments
I configure prost to derive let mut config = prost_build::Config::new();
config.type_attribute(".", "#[derive(Serialize)]");
config.type_attribute(".", "#[serde(rename_all = \"camelCase\")]"); Are there ways in which the proto3 JSON mapping differs from what serde can do? |
@adeschamps - I haven't tested, but there is at least one obvious problem with that approach. What if your protobuf fields used underscores in the |
Doesn't protobuf convert field names to camel case for JSON anyway? |
Ah yes, you appear to be correct. Maybe I will give this a whirl and see if it passes the conformance tests. |
I'm interested in doing something similar and I would love to know if this works too! |
Hey all, this has been a really good discussion. I don't have any plans to use or work on proto3 JSON support, but if someone can figure out a way to do it in a straightforward way, ideally by leveraging Serde, then I'm all for it. @cretz hopefully you've already seen it already, but there is an in-tree conformance test crate which skips the JSON tests. You should be able to hook that up, and add the JSON/Serde data to the protobuf crate. |
I am considering doing this as something I'm trying to support at work, is anyone else actively working on this? I was planning on building a new derive which will generate a |
I have as of recent developed a need for |
I was digging into turning my prost generated models into something I can use with Serde json/yaml - mostly through manipulating For example, if have a proto that outputs an enum of: #[derive(serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "camelCase")]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
#[repr(i32)]
pub enum MyEnum {
First = 0,
Second = 1,
} (I left on my serde attributes, so you can see them) - I think we will need a custom deserialiser for turning enum JSON into Rust values. Since it can take either the name (e.g. "First") or the integer value (e.g. 0). According to the spec:
I don't think standard serde attributes are going to be good enough to handle this out of the box, we're going to need some custom tooling. I'm just poking at prost<->serde stuff atm, but thought I'd share if it helps. |
It's very much beta software, and lacks complete coverage of all the well-known-types (see the issue tracker) as I've currently only implemented the ones needed by IOx, but I recently released pbjson-build which derives compliant serde implementations for prost generated types. I could not find a nice way to do this using serde annotations as suggested on this issue, as the enumerations, 64-bit integers, and generally loose deserialization requirements made this at least not obvious to myself. Disclaimer: I am the author of this crate |
Adds support for the "Cosmos JSON" `PublicKey` serialization, e.g.: {"@type":"/cosmos.crypto.ed25519.PubKey","key":"sEEsVGkXvyewKLWMJbHVDRkBoerW0IIwmj1rHkabtHU="} Encoding follows Protobub JSON conventions, with binary data encoded as standard (i.e. non-URL safe) Base64. However, note that it's structurally still a bit different from the Protobuf JSON encoding for public keys, and thus entails a custom solution. Also note that there is unfortunately not yet a general solution for Protobuf JSON encoding for `prost::Message`: tokio-rs/prost#75
Adds support for the "Cosmos JSON" `PublicKey` serialization, e.g.: {"@type":"/cosmos.crypto.ed25519.PubKey","key":"sEEsVGkXvyewKLWMJbHVDRkBoerW0IIwmj1rHkabtHU="} Encoding follows Protobub JSON conventions, with binary data encoded as standard (i.e. non-URL safe) Base64. However, note that it's structurally still a bit different from the Protobuf JSON encoding for public keys, and thus entails a custom solution. Also note that there is unfortunately not yet a general solution for Protobuf JSON encoding for `prost::Message`: tokio-rs/prost#75
Adds support for the "Cosmos JSON" `PublicKey` serialization, e.g.: {"@type":"/cosmos.crypto.ed25519.PubKey","key":"sEEsVGkXvyewKLWMJbHVDRkBoerW0IIwmj1rHkabtHU="} Encoding follows Protobub JSON conventions, with binary data encoded as standard (i.e. non-URL safe) Base64. However, note that it's structurally still a bit different from the Protobuf JSON encoding for public keys, and thus entails a custom solution. Also note that there is unfortunately not yet a general solution for Protobuf JSON encoding for `prost::Message`: tokio-rs/prost#75
+1 currently relying on envoy proxy to handle transcoding from json to protobuf and vice versa -> important to note hacking Serialize / Deserialize into the output does not handle nested oneof structures, among other things such as lowercase fields, which breaks compliance |
Using Serde also fails for |
Json support is listed in the roadmap #624 . What is the plan for achieving this? Can we work on integrating pbjson (great work btw!) into this project somehow? Ideally, it would simply be a case of enabling an option in prost-build, and a feature flag on prost-types. |
There currently isn't much of a plan since I don't have time to work on feature work here right now. The 1.0 plan is more of a want than actually something I think we can achieve right now. I think we could eventually try to get pbjson merged into here. |
I would be more than happy to help make this happen, just let me know. I don't foresee any issues from my side with a potential donation if that is something you would be interested in. It would be awesome to resolve the current pbjson-types vs prost-types situation (influxdata/pbjson#75) |
Yeah, I think to move this forward the best way would be to write a proper proposal that I can review in an issue that way we can agree on what makes sense before anyone writes a PR. Feel free to tag me in that issue if you're interested in taking that on. 😄 |
Found one, protobuf
and then in build.rs
|
I'm realistically not going to have time to undertake this in the near term, but would be happy to help with IP clearance, etc... if someone else wishes to pick this up.
Off the top of my head, the major differences are:
Using serde derive directly is fine if you just want a JSON serialization, if you want the protobuf serialization, you are very likely to run into mismatches between the two |
If someone is looking to get the same serialization for For example, for the following proto definition: message C {
oneof some_field {
A a_variant = 6;
B b_variant = 7;
}
}
message A {
...
}
message B {
...
} The following configuration in config
.type_attribute(".", "#[derive(serde::Serialize, serde::Deserialize)]")
.type_attribute(".", "#[serde(rename_all = \"snake_case\")]")
.field_attribute("C.some_field", "#[serde(flatten)]") |
Are there any plans to support the official proto3 JSON mapping in prost-build? When building https://github.com/cretz/prost-twirp I have found a need for it. Even if it is not supported directly, the field/type attributes in the prost-build config are still difficult to use for this purpose. I suppose I could parse the protobuf myself w/ the other lib here and then create the field/type attributes though it would be nice if prost-build gave me the AST.
The text was updated successfully, but these errors were encountered: