Skip to content

Add model def objectid support#778

Closed
superkhau wants to merge 2 commits into
masterfrom
add-model-def-objectid-support
Closed

Add model def objectid support#778
superkhau wants to merge 2 commits into
masterfrom
add-model-def-objectid-support

Conversation

@superkhau

Copy link
Copy Markdown
Contributor

Short term fix for ObjectId support.

Connect to strongloop-internal/scrum-loopback#625
See also https://github.com/strongloop-internal/scrum-loopback/issues/566

@superkhau

Copy link
Copy Markdown
Contributor Author

@ritch Review please.

@superkhau

Copy link
Copy Markdown
Contributor Author

@slnode test please

@superkhau
superkhau force-pushed the add-model-def-objectid-support branch 2 times, most recently from 41487e1 to e5ea9c9 Compare November 30, 2015 19:49
@superkhau

Copy link
Copy Markdown
Contributor Author

@bajtos Review please.

Comment thread lib/objectid.js Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should depend on mongodb directly in the juggler. We should contribute ObjectID some other way. It should work without the mongodb connector (eg. in the browser).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another option is to optionally depend on mongodb (or similar, eg. an ObjectID module). Sort of like this:

try {
  mongodb = require('mongodb');
} catch(e) {
  if (!isNotFound(err)) { 
    throw e;
  }
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My initial impl had our own ObjectId definition that delegated to mongo's object id, which we can move towards in the long term update. Will add it to the notes there.

For the short term I will use the try/catch you suggested.

@superkhau
superkhau force-pushed the add-model-def-objectid-support branch from e5ea9c9 to ff15df6 Compare December 2, 2015 00:50
Comment thread lib/objectid.js Outdated

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ritch LGTY?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be honest, I don't like adding mongodb dependency to juggler at all. Remember, there is no guarantee that mongodb module referenced by juggler will be the same module as referenced by loopback-connector-mongodb. In fact, this will be the most frequent case.

app
  node_modules
    loopback-datasource-juggler
      node_modules
        mongodb
    loopback-connector-mongodb
      node_modules
        mongodb

As a result, you are registering a type (constructor function) that is actually never used by the connector, because the connector has it's own local type (constructor function).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TBH, I don't like it either, but it was the simplest way to get the full power of an ObjectId (all it's validations, unique string generation, other functions etc) in one shot. The other option is to just not use mongodb at all and come up with our own unique implementation for each function. However, this is not a 5 point job. I figure in the long term proposal task I have for this sprint, we can decide whether we want to come up with our own implementations for each function or use source code from other projects, etc.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would have an API similar to https://docs.mongodb.org/manual/reference/object-id/ basically.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another thing to consider is the option to allow user-configurable ObjectId types. Like in model-config.json, we allow {"objectid": "../path/to/your/custom/objectid"}, or something along those lines.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes me wonder if there is a way how to allow loopback-connector-mongodb to call modelTypes.registerType(ObjectId) during connector/datasource initialisation. That way we can keep the implementation in mongodb and still have ObjectID available in the app.

Of course, that would not work for isomorphic app in the browser, so it would be still a short-term fix.

Anyways, I guess you spend more time thinking about this issue than I did, and if this is the best short-term solution we have, then I can live with it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes me wonder if there is a way how to allow loopback-connector-mongodb to call modelTypes.registerType(ObjectId) during connector/datasource initialisation. That way we can keep the implementation in mongodb and still have ObjectID available in the app.

I have thought about this too, but figured it would be harder to implement because we don't expose that part of the lib in DAO. The long term solution I had in mind and discussed with @ritch is an app-level registry for datatypes. During boot time, we would register all basic built in datatypes, then register any custom types. Then at run time, we can dynamically register/deregister new datatypes. Something along the lines of:

app.datatypes.add(ObjectId);
app.datatypes.list();
app.datatypes.remove(ObjectId);

Or use an a K/V array for datatypes, etc. We can discuss further in the long-term proposal with regards to implementations.

@bajtos

bajtos commented Dec 2, 2015

Copy link
Copy Markdown
Member

@superkhau please make sure the redis build failure is not related to your change

@superkhau

Copy link
Copy Markdown
Contributor Author

@bajtos Is there a way to target redis specifically? All my tests are green locally.

@bajtos

bajtos commented Dec 3, 2015

Copy link
Copy Markdown
Member

Is there a way to target redis specifically? All my tests are green locally.

Sorry for the confusion, I was referring to dependant loopback-connector-redis. There are more test failures reported now. They may be unrelated to this patch, just make sure to check & verify it's true.

- Remove console.log from unit test
@superkhau

Copy link
Copy Markdown
Contributor Author

The redis tests are failing on its own.

@superkhau superkhau assigned bajtos and unassigned ritch Dec 10, 2015
@superkhau

Copy link
Copy Markdown
Contributor Author

@bajtos Reassigning to you for review as @ritch is probably too busy to review this. Please let me know how to move forward with this.

Comment thread lib/objectid.js Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing semicolon at EOL, please add.

@bajtos

bajtos commented Dec 11, 2015

Copy link
Copy Markdown
Member

@superkhau please add few tests to the test-suite run by all connectors (see test/common.batch.js) to ensure this new ObjectID type is correctly persisted and loaded when using e.g. relational (SQL) databases.

Comment thread lib/types.js

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any way how to register ObjectID as an alias for ObjectId? Or is it automatically handled?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is already registered as an alias in the ObjectId class definition, so it should work properly. I added an e2e test to prove it.

@bajtos bajtos removed their assignment Dec 11, 2015
@superkhau

Copy link
Copy Markdown
Contributor Author

@bajtos Updated with the comments from your review. Can you PTAL again?

@superkhau superkhau assigned bajtos and unassigned superkhau Dec 14, 2015
Comment thread lib/objectid.js

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@superkhau AFAICT, this silently swallows any mongodb parse errors, which does not look like a good thing to me. Could you please explain what is the rationale for this, why we need to give require('mongodb').ObjectId errors a special treatment?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was suggested by @ritch in a previous comment in this issues history. I think it was for uses cases where mongodb is not available (ie. the browser).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair enough. Please add a debug log to let the user know ObjectId will be undefined because mongodb was not found.

debug('Cannot load mongodb, ObjectId will be undefined. %s', e.stack);

@bajtos

bajtos commented Dec 15, 2015

Copy link
Copy Markdown
Member

@superkhau I am missing unit-tests to be run by connectors, per my earlier comment:

please add few tests to the test-suite run by all connectors (see test/common.batch.js) to ensure this new ObjectID type is correctly persisted and loaded when using e.g. relational (SQL) databases.

@bajtos bajtos assigned superkhau and unassigned bajtos Dec 15, 2015
@superkhau

Copy link
Copy Markdown
Contributor Author

@slnode test please

@superkhau
superkhau force-pushed the add-model-def-objectid-support branch from a469872 to 5d987f6 Compare December 18, 2015 04:17
Comment thread test/datatype.test.js

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bajtos Added data type tests here.

@superkhau

Copy link
Copy Markdown
Contributor Author

@superkhau superkhau assigned bajtos and superkhau and unassigned superkhau and bajtos Dec 18, 2015
@bajtos

bajtos commented Dec 22, 2015

Copy link
Copy Markdown
Member

One more comment: #778 (comment)

@superkhau after you address ^^^, then please rebase the patch on top of the current master, clean up the commit history and merge this without waiting for me. IIUC this is a backwards-compatible change targeted for LoopBack LTS, in which case you need to back-port it to 2.x too.

@bajtos

bajtos commented Dec 22, 2015

Copy link
Copy Markdown
Member

@bajtos bajtos added this to the #Epic: LoopBack LTS milestone Dec 22, 2015
@mrbatista

Copy link
Copy Markdown
Contributor

@superkhau when will this patch be merged?

Thanks.

@superkhau

Copy link
Copy Markdown
Contributor Author

@mrbatista Soon I believe, I need to write a few more tests to confirm the data persistence with relational connectors, but after that it's all good.

@bajtos

bajtos commented Apr 6, 2016

Copy link
Copy Markdown
Member

@superkhau I am not sure what's the status of this work. If we decide to eventually land this, then I would like you to try an alternative approach: get the implementation of ObjectID directly from bson/lib/bson/objectid.js. I believe the mongodb driver we use does basically the same, so it should be safe to bypass mongodb and load the definition directly. If it works, then this solution will reduce the footprint of juggler in applications that don't use MongodB.

@superkhau

Copy link
Copy Markdown
Contributor Author

@bajtos This has been stale for a long time and is probably not a good solution now. Let's do what you propose (as a new feature/PR instead).

@bajtos

bajtos commented Apr 8, 2016

Copy link
Copy Markdown
Member

ok, I'm closing this PR then.

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

Successfully merging this pull request may close these issues.

4 participants