mora
mora copied to clipboard
Does not handle documents with UUID's as Ids
If your MongoDB documents contain a certain type of UUID for an _id, Mora returns the ID as an object like this:
"_id": { "Kind": 3, "Data": "ABnJswg/6EKEoibo1A6/yQ==" }
It does not appear possible to interact with the document level of the API (GET,PUT,DELETE) using this format with Swagger.
It looks like Mora supports some form of Hex object id. Not sure why this type shows up like this or what "Kind" refers to. These were documents which had a .NET GUID as an ID and were added to MongoDB using the official C-Sharp driver.
In MongoClient the id looks like: BinData(3,"ABnJswg/6EKEoibo1A6/yQ==")
In Robomongo the id looks like: LUUID("c1fad936-f455-d543-be73-07970d6eac1e") or with .NET id encoding like: NUUID("36d9fac1-55f4-43d5-be73-07970d6eac1e")
I know this is just a demo project and I am rather new to GoLang but, if you have some general advice about how to solve this, I would be willing to try a fix and submit a pull request.
Thank you for reporting this. I will have a look at the code and your example to see what we can do about it.
In the docs of mgo i found:
type Binary struct {
Kind byte
Data []byte
}
which is most likely used for your document.
As this type does not have (yet) its own Marshaling method, it will use its exposed fields.
Now the question is, what format should it use? MUUID("....") ?
Sorry for taking so long to reply.
In the source code here: https://github.com/go-mgo/mgo/blob/v2/bson/bson.go there are some comments that mention kinds of binary values. The 0x03 "Kind" definitely indicates a UUID
// Binary is a representation for non-standard binary values. Any kind should
// work, but the following are known as of this writing:
//
// 0x00 - Generic. This is decoded as []byte(data), not Binary{0x00, data}.
// 0x01 - Function (!?)
// 0x02 - Obsolete generic.
// 0x03 - UUID
// 0x05 - MD5In Robomongo the id looks like: LUUID("c1fad936-f455-d543-be73-07970d6eac1e")
// or with .NET id encoding like: NUUID("36d9fac1-55f4-43d5-be73-07970d6eac1e")
// 0x80 - User defined.
//
type Binary struct {
Kind byte
Data []byte
}
As to how to represent it in the API and JSON, that is tougher. You wouldn't want to use the base64 directly as it would require URL encoding because of the "/" character.
The RoboMongo docs mention a Kind "4" not listed here that corresponds to the "new Standard Encoding" that may get implemented in a future release. There is a JavaScript library that demonstrates their proposal. I would be happy just supporting one type - the type they hope to support in the shell client as opposed to Java/.NET/Python which I think currently are a mess to work with.
The proposed format is:
UUID("xxxxxxxx-xxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")
Which in the JSON or URL would be patterned as just: "xxxxxxxx-xxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
I assume there would have to be some sort of pattern matching done on the input to determine if the document ID is being given in this format and, if so, it gets converted to base64 as a kind "0x03" when sent to mgo because that is all they currently support. (Note JS implementation in uuidhelpers.js below.)
If they eventually support the new format in MongoDb, hopefully, mgo will follow suit and the value can just be wrapped in an out of a struct with Kind = 0x04.
Does this approach even sound worth trying or am I missing something really important?
Ref: http://robomongo.org/articles/uuids.html https://jira.mongodb.org/browse/SERVER-3153 https://github.com/mongodb/mongo-csharp-driver/blob/master/uuidhelpers.js
Thank you for the elaborate response.
Technically, your suggestion will definitely work. I am a bit concerned whether this change will result in a backward incompatible change. What if developers already decided to use a UUID as string for the _id ? Maybe that is the reason why the other tools use a prefix? Perhaps the solution is to have a setting (default=false) that converts UUID to type 3 Binary values.
Possibly related: I've submitted a pull request at #32 that changes mora's output to use MongoDB's extended JSON specification. It also allows for querying using the extended JSON spec.
I've only briefly played around with binary UUID data, and it does change the output to the standard for binary data described in the spec. I can't quite figure out how to query by binary data, but it seems like it should be possible. In any case, just thought I'd mention it, since the extended json might offer the most universal way of dealing with this for a straight JSON API.