Reputation: 3991
I'm using Arango 3.3.10
I've created a fox service used for user login and management. When logging in I get the username and then I've tried retrieving the document using a couple methods - .firstExample & ._query
I successfully get the document, but each time I get it has a different _key, _rev, and _id.
It doesn't do it if I run the queries from the "Queries" tool in the ArangoDB web interface. Any ideas?
EDIT: I solved the issue, but wanted to provide further details.
In the collection I'm testing against, there is only 1 document. It has fields: username
, email
, and a hash/salt for password.
When I retrieve the document, I'm using the .firstExample function of the arangojs driver. I whittled down my code to the point that firstExample was the only db interaction happening and immediately afterward it would send the result back to the client. The code retrieves the document successfully, but each time the document has a different _key, _rev, and _id.
If I login to the database web interface, I can see the solitary document, and I can see that the _key, _rev, and _id changes each time I call my Foxx api. To my knowledge the .firstExample function should never produce this result.
What I found is that it only does this when the field username
is set to the string 'admin'. If I change the username
field to anything else, this behavior stops and the document is retrieved as expected and the _key, _rev, and _id all stay the same.
I believe this to be a bug, but I don't know if it's a bug in the DB or with the arangojs driver. I'm leaning toward arangojs driver because this behavior did not manifest when running the query using the query tool within the ArangoDB web interface.
UPDATE: Further details emerge So after further testing it seems that the setup script for the Foxx service is somehow being triggered. The setup script creates a default user named 'admin'. So what seems to be happening is somehow the setup script runs when the API is hit, it recreates the user each time and assigns a new _key, _rev, and _id, then it gets sent back to me. So the result is the admin user gets removed and recreated each time.
I've narrowed the code down to absolute essentials, and the setup script is still triggered:
index.js
'use strict'
const userRoutes = require('./user-routes')
module.context.use(userRoutes)
user-routes.js
'use strict'
const joi = require('joi'
const createRouter = require('@arangodb/foxx/router')
const usersColl = module.context.collection('users')
const router = createRouter()
router
.post('/test', function (req, res) {
const username = req.body.username
try {
const user = usersColl.firstExample('username', username)
res.send(user)
} catch (e) {
res.throw(404, e)
}
})
.body(
joi
.object({
username: joi.string().required()
})
.required(),
'Username'
)
.summary('Username test')
.description('Username test')
manifest.json
{
"engines": {
"arangodb": "^3.0.0"
},
"main": "index.js",
"scripts": {
"setup": "scripts/setup.js"
},
"provides": {
"@pulse/user-mgmt": "1.0.0"
}
}
Why would this trigger the setup script when calling the API?
Upvotes: 0
Views: 278
Reputation: 2349
As mentioned above, it looks like 'scripts/setup.js' was running every time the service was invoked, while the Foxx microservice was running in 'Development' mode. if running in 'Production' mode, it will only run setup once on server start, and then keep the compiled version of the code cached.
'Development' mode can be very useful where you're using an IDE like WebStorm and it auto deploys code from your GIT directory into your ArangoDB App directory for your microservice. It's useful because every change you code is reflected in the next execution cycle of the microservice.
It's important not to run Foxx microservices in 'Development' mode when performance is an issue, or there is notable logic in your setup scripts, as it can really slow it down.
Glad we got to the bottom of it, and it was a good lesson learnt.
Upvotes: 1
Reputation: 3991
I solved it. Seems that the username admin must be reserved, because the problem only occurs when trying to get a user with that username. Other users return fine. I'll have to change my setup script to create the default user with a different name.
UPDATE Also, I'm not pulling from the system collection of users, this is my own custom collection. The document has a field called username. If this field is set to 'admin' the problem above occurs. Seems to be a very strange bug.
Upvotes: 0
Reputation: 9097
firstExample
will retrieve a document that matches the specified pattern. If multiple documents match the pattern, then one of these documents will be returned. But it is unpredictable which of the matching documents it will be.
So if multiple documents qualify, with firstExample
you may get a "random" one.
Is there a unique index on the username attribute, so it is made sure there is at most one document for each username?
If so, please share the exact commands you are using the retrieve the document plus an example document from the collection in question plus its indexes.
Upvotes: 2