Summary
This one is causing me a lot of pain.
After a lot of debugging it looks like Loopback is automatically assuming an ID value on the URI (e.g. /api/myModel/:id) is a Number.
So something like this:
curl -X GET --header "Accept: application/json" "http://192.168.99.100:3000/api/profiles/5828128208445124611"
Does not work because Loopback is automatically converting the BIGINT value to Number, which rounds 5828128208445124611 to 5828128208445125000.
So the above GET request example, results in an error:
{
"error": {
"name": "Error",
"status": 404,
"message": "Unknown \"Profile\" id \"4828128208445124611\".",
"statusCode": 404,
"code": "MODEL_NOT_FOUND",
"stack": "Error: Unknown \"Profile\" id \"4828128208445124611\".\n at Function.convertNullToNotFoundError (/usr/src/app/node_modules/loopback/lib/persisted-model.js:81:17)\n at invokeRestAfter (/usr/src/app/node_modules/loopback/node_modules/strong-remoting/lib/rest-adapter.js:453:25)\n at /usr/src/app/node_modules/loopback/node_modules/async/lib/async.js:607:21\n at /usr/src/app/node_modules/loopback/node_modules/async/lib/async.js:246:17\n at iterate (/usr/src/app/node_modules/loopback/node_modules/async/lib/async.js:146:13)\n at /usr/src/app/node_modules/loopback/node_modules/async/lib/async.js:157:25\n at /usr/src/app/node_modules/loopback/node_modules/async/lib/async.js:248:21\n at /usr/src/app/node_modules/loopback/node_modules/async/lib/async.js:612:34\n at interceptInvocationErrors (/usr/src/app/node_modules/loopback/node_modules/strong-remoting/lib/remote-objects.js:681:22)\n at /usr/src/app/node_modules/loopback/node_modules/async/lib/async.js:154:25\n at /usr/src/app/node_modules/loopback/node_modules/async/lib/async.js:154:25\n at /usr/src/app/node_modules/loopback/node_modules/async/lib/async.js:154:25\n at execStack (/usr/src/app/node_modules/loopback/node_modules/strong-remoting/lib/remote-objects.js:488:7)\n at RemoteObjects.execHooks (/usr/src/app/node_modules/loopback/node_modules/strong-remoting/lib/remote-objects.js:492:10)\n at phaseAfterInvoke (/usr/src/app/node_modules/loopback/node_modules/strong-remoting/lib/remote-objects.js:652:10)\n at runHandler (/usr/src/app/node_modules/loopback/node_modules/loopback-phase/lib/phase.js:135:5)"
}
}
Enabling debugging output in Loopback shows:
Tue, 17 May 2016 19:52:05 GMT loopback:connector:postgresql SQL: SELECT "user_id","first_name","last_name","email","phone","created_at","updated_at","created_by","updated_by" FROM "user_profile"."profile" WHERE "user_id"=$1 ORDER BY "user_id" LIMIT 1
Parameters: ["4828128208445125000"]
So clearly the value 4828128208445124611 gets rounded into 4828128208445125000.
I verified that this happens right at the beginning, using an operations hook:
Profile.observe('access', function logQuery(ctx, next) {
console.log('Context', ctx);
next();
});
The output shows the ID is already truncated:
query:
{ where: { userId: '4828128208445125000' },
limit: 1,
offset: 0,
skip: 0 },
Is this a known issue? I couldn't find documentation or bug reports etc. on this.
Custom Remote Method
Btw, adding my own remoteMethod where I have control over the Input Argument (i.e. forcing it to be a string) and then calling findById programmatically works correctly:
Profile.get = function(id, cb) {
console.log('ID:', id);
Profile.findById(id).then(function(profile) {
console.log('FindById: profile', profile);
cb(null, profile);
});
};
Profile.remoteMethod(
'get',
{
accepts: [
{arg: 'id', type: 'string', required: true}
],
http: {path: '/:id/get', verb: 'get'},
returns: {arg: 'profile', type: 'object'}
}
);
You can see above I simply am copying the default findById REST endpoint, only difference is I add get to the end of the URI /api/profiles/:id/get. The logic just defers to Profile.findById().
Calling it:
curl -X GET --header "Accept: application/json" "http://192.168.99.100:3000/api/profiles/4828128208445124611/get"
Works with no issues.
Summary
This one is causing me a lot of pain.
After a lot of debugging it looks like Loopback is automatically assuming an ID value on the URI (e.g.
/api/myModel/:id) is a Number.So something like this:
curl -X GET --header "Accept: application/json" "http://192.168.99.100:3000/api/profiles/5828128208445124611"Does not work because Loopback is automatically converting the BIGINT value to Number, which rounds
5828128208445124611to5828128208445125000.So the above GET request example, results in an error:
Enabling debugging output in Loopback shows:
So clearly the value
4828128208445124611gets rounded into4828128208445125000.I verified that this happens right at the beginning, using an operations hook:
The output shows the ID is already truncated:
Is this a known issue? I couldn't find documentation or bug reports etc. on this.
Custom Remote Method
Btw, adding my own remoteMethod where I have control over the Input Argument (i.e. forcing it to be a string) and then calling findById programmatically works correctly:
You can see above I simply am copying the default findById REST endpoint, only difference is I add
getto the end of the URI/api/profiles/:id/get. The logic just defers to Profile.findById().Calling it:
Works with no issues.