-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Spike: robust handling of ObjectID type for MongoDB #3456
Comments
There is a pull request in progress to improve this part, see loopbackio/loopback-datasource-juggler#1783 and also the discussion in #3602 |
When working on the task #4148, the the problem is spot in Once this is being fixed:
|
Ok, I am done with the spike. Here is the spike report. POC is in the form of test cases. Make sure to checkout the |
@hacksparrow I like the spike report summary 👍 When I try to understand the problems related to ObjectID, I am always lost at a good description of the expected behaviour, is https://github.com/strongloop/loopback-connector-mongodb#handling-objectid still a valid description for the new proposal? If not could you maybe write a new one? |
How to describe relations with ObjectID? For example
Thank you. |
@mikeevstropov we haven't gotten to the implementation part yet, but I'd like |
@mikeevstropov currently you can do // foreign key
@belongsTo(() => Customer,
{}, //relation metadata goes in here
{// property definition goes in here
mongodb: {dataType: 'ObjectId'}
})
customerId: string; |
@hacksparrow I like the idea of getting rid of ( or set aside for now) If I remember correctly, now
From your summary, 3 will be handled in DAO, 👍 can't wait to see it. |
The only place where we will be working with "real" ObjectID will be within the MongoDB connector. Even DAO need not know anything about ObjectIDs, it just applies the coercing function, which will be provided by the respective connectors. Users will never have to think in ObjectID once they have set |
I like removing juggler layer's coercion a lot. It's much better to give connector the full control. It would be easier for having unified behavior in lb3/lb4/other ORM. I have a question for the returned data's type. IIUC, according to test case, the returned data will always be in string format. Is it worth to allow choose between type objectId/string? E.g. connector's coercion function returns either objectId/string based on config, and juggler returns the data as is? Other than ^ the solution looks reasonable to me. |
Is there a condition where someone would want to use ObjectID instead of string? |
@hacksparrow I think this test case is an example. |
That was written for the existing behavior, we will get rid of the behavior and the test. I can't think of any situation where one would want to work with ObjectIDs than string. |
I see fair enough, not sure how to approve the proposal since it's not a PR :p I like the new proposal it's very straightforward 💯 |
I see 👍 |
Can you show an example of what you have on mind? A real property definition. |
@hacksparrow @agnes512 @jannyHou I have few more suggestions to consider, PTAL at my comments in loopbackio/loopback-connector-mongodb#591 and loopbackio/loopback-datasource-juggler#1861. |
Thanks @bajtos I commented here loopbackio/loopback-datasource-juggler#1861 (comment) |
OK, here is the new spike report - https://github.com/strongloop/loopback-connector-mongodb/blob/6732fe7589d061632df8990ef4f11b8d48d138d9/SPIKE.md. This approach is simpler and does not require changes to Juggler. Thanks @bajtos for the discussion. |
While discussing the first SPIKE, I highlighted to @bajtos that Juggler also requires refactoring. The points are captured in #889 (comment).
So, while we will not be using the first approach, it was a good exercise in pointing out areas of refactoring in Juggler, which was missed in the original Juggler Refactor Epic. |
Created follow up tasks.
4 and 5 are somewhat related but not a requirement, they were discovered and created out of the first spike. @bajtos are we good to close this now? |
Sure 👍🏻 |
MongoDB is tricky.
ObjectID
type for primary keys.ObjectID
is represented as astring
when converted to JSON'some-id' !== ObjectID('some-id')
.As a result, both PK and FK properties must use
ObjectID
as the type, and coercion must be applied where necessary.Ideally, I'd like LB4 to define MongoDB PK and FKs as follows:
{type: 'string', mongodb: {dataType: 'ObjectID'}}
Even better,
dataType: 'ObjectID'
should be automatically applied by the connector for PK and FKs referencing ObjectID PKs.For example:
For v1, I suppose we can ask developers to provide dataType manually.
With this setup in place,
id
andcategoryId
properties should be always returned as strings from DAO and connector methods.This is tricky to achieve for the PK property, because juggler overrides user-supplied type with connector's default type when the PK is generated by the database. See
DataSource.prototype.setupDataAccess()
Can we rework MongoDB connector to hide ObjectID complexity as an internal implementation detail and always use string values in public APIs? Accept ids as strings and internally convert them to ObjectID. Convert values returned by the database from ObjectID to strings.
Downside: this is not going to work for free-form properties that don't have any type definition and where the connector does not know that they should be converted from string to ObjectID. But then keep in mind that JSON cannot carry type information, therefore REST API clients are not able to set free-form properties to ObjectID values even today.
See also #3387
Acceptance criteria
For every property defined as
{type: 'string', mongodb: {dataType: 'ObjectID'}}
, including properties defined in nested/embedded models:filter.where
, but alsofindById
andreplaceById
), it converts string values to ObjectID. The conversion is applied to non-trivial conditions too, e.g.{where: {id: { inq: ['my-objectid-1', 'my-objectid-2'] }}}
Tasks & deliverables
A PoC to verify feasibility of the design where
ObjectID
type is hidden as an implementation detail of the MongoDB connector and all other LB layers (juggler, Repository, REST APIs) usestring
type instead.A list of well-defined follow-up tasks to implement the PoC. (This will be a semver-major release of the MongoDB connector.)
The text was updated successfully, but these errors were encountered: