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

Serializing a BSON document to a simple JSON #354

Closed
erfanium opened this issue Apr 19, 2022 · 6 comments
Closed

Serializing a BSON document to a simple JSON #354

erfanium opened this issue Apr 19, 2022 · 6 comments
Assignees

Comments

@erfanium
Copy link

erfanium commented Apr 19, 2022

I wonder is there any way to serialize a bson document to a simple json (not extjson)?
I know there's two similar methods Bson::into_relaxed_extjson and Bson::into_canonical_extjson but they convert them into extjson, not simple json, which i don't want.

Here's is an example of my expected result.

let doc = bson!({ "x": 5i32, "_id": oid::ObjectId::new(), "d": bson::DateTime::now() });


let simple_json = doc.clone().into_simple_json();
println!("{}", simple_json); // { "x": 5, "_id": <hexstring>, "d": "2020-06-01T22:19:13.075Z" }

This is exactly the same behavior of JSON.stringify(bson_document) in JavaScript

@kmahar
Copy link

kmahar commented Apr 19, 2022

Hi @erfanium, thanks for reaching out.

There isn't a way to do this directly from a Bson right now.

We recently discussed doing something that might help in this case: RUST-1178. See #191 for some related discussion. What that ticket proposes is adding a way to opt into having the driver produce "plain" JSON for types such as bson::DateTime and oid::ObjectId.

One workaround currently available would be to define a type modeling your data that implements Serialize and Deserialize. You could then deserialize your BSON data into that type, and serialize the type into plain JSON. See here for some details on how to do that.
Beyond that, another option would be to implement your own logic, something like this, that serializes BSON types the way you want them to be represented.

@kmahar kmahar removed the triage label Apr 19, 2022
@erfanium
Copy link
Author

erfanium commented Apr 20, 2022

Thank you @kmahar

another option would be to implement your own logic, something like this

I wanna add that it's not really my own logic, MongoDB Atlas Data Api uses this logic for response bodies, so I think it's necessary to have simple-json serialization in official bson libs.
https://www.mongodb.com/docs/atlas/api/data-api-resources/#find-a-single-document

@kmahar
Copy link

kmahar commented May 24, 2022

@erfanium Atlas Data API supports both plain and extended JSON, with the caveat that the plain format can lead to data loss because not all BSON types are representable in plain JSON (see docs).
An additional caveat worth noting is that even for types that can be represented in plain JSON, it is impossible for many of them to be losslessly round-tripped from Document -> JSON -> Document. For example, the "plain" JSON of an ObjectId is a string, and so if you have a document like doc! { "_id": oid::ObjectId::new() }, serialize it to plain JSON, and then deserialize the JSON back into a Document, the BSON library cannot tell that the field was initially an ObjectId, and so it will be decoded as a string instead: doc! { "_id": "string_representation_here" }.

Due to these limitations, we've chosen not to support plain JSON in this library at this time. If you want to use this BSON library with Atlas Data API I would strongly recommend having your endpoints return and accept extended JSON, as it will ensure you do not lose any data or inadvertently change the data type of any fields in your documents.

@kmahar kmahar closed this as completed May 24, 2022
@erfanium
Copy link
Author

@kmahar

Atlas Data API supports both plain and extended JSON, with the caveat that the plain format can lead to data loss because not all BSON types are representable in plain JSON (see docs).

That was all I need, Thank you!

@DanieliusDev
Copy link

I would like to quickly bring this back and ask: since we cannot make both JSON and BSON with one struct, is there really a point of using bson features like uuids and dates instead of just strings?

@erfanium
Copy link
Author

erfanium commented Jun 9, 2023

@gamertike databases can perform more optimizations when they know a field is a UUID, or Date
also it helps data integrity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants