-
-
Save jgeewax/3b351d3522fdf061bdea to your computer and use it in GitHub Desktop.
var express = require('express'); | |
var app = express(); | |
var gcloud = require('gcloud')({ /* extra config here */ }); | |
var dataset = gcloud.datastore.dataset({ /* projectId: my-project */ }); | |
// Set the trace ID on a per-request basis via middleware | |
// (See http://expressjs.com/guide/writing-middleware.html) | |
app.use(function(req, res, next) { | |
// Need to double check that this works from a thread safety perspective. | |
gcloud.setTraceContext(req.headers['X-Cloud-Trace-Context']); | |
}); | |
// Get companies from the datastore. | |
app.get('/company/:id', function(req, res, next) { | |
var key = dataset.Key(['Company', req.params.id]); | |
// This request will have the trace ID that was set by the middleware. | |
// So whatever was in the request header will be automatically forwarded along. | |
dataset.get(key).on('data', function(entity) { | |
res.send(entity); | |
}); | |
}); |
And this opens the question (@stephenplusplus), can we change the parent only and have the decorator inherit down somehow...? ie...
Man, gists really need email notifications or something. I'm always one step behind.
But yeah, I would expect the user to expect an inheritance model, where anything set on the highest level cascades downwards, and the lowest object wins in the event of a conflict:
var gcloud = require('gcloud')({
decorateRequest: function(reqOpts) {
reqOpts.headers['A'] = 1;
reqOpts.headers['B'] = 1;
return reqOpts;
}
});
var bucket = gcloud.bucket({
decorateRequest: function(reqOpts) {
reqOpts.headers['A'] = 2;
return reqOpts;
}
});
bucket.getMetadata();
// GET https://...
// A: 2
// B: 1
Sure, but the example we're talking about is...
var gcloud = require('gcloud');
var bucket = gcloud.bucket();
var threadLocalgcloud = gcloud({
decorateRequest: function(reqOpts) {
reqOpts.headers['A'] = 1;
return reqOpts;
}
});
bucket.getMetadata();
// GET https://...
// A: 1
That is, I mess with the parent somehow, and the pre-created child gets updated... It seems like that wouldn't be possible to me.... right?
In that example, bucket.getMetadata()
would not know anything about the decorated request options. You would have to access the bucket from threadLocalgcloud.bucket()
to have that stuff on there.
In a practical use, if I need to decorate all requests, I would do this:
var gcloud = require('gcloud')({
decorateRequest: function(reqOpts) {
reqOpts.headers['A'] = 1;
reqOpts.headers['B'] = 1;
return reqOpts;
}
});
Each invocation of
dataset()
returns a fresh auth client. So having to create one on each GET means you'd also end up doing a fresh token grab every time. But without scoping request option manipulation to the object, you'd inevitably run into concurrency issues, so it might be a fair trade off for what is not the 99% use case?If not, we can go the forking route, but it'd have to be from a new method (like
dataset.clone()
) that would reuse/override options.And an option that is less "it's as easy as 1-2-3" for the user, but possibly easier to grasp / re-usable and expandable down the road:
There are many ways to implement the above concept with/without using
extend
, using helper functions, etc, so if it doesn't suit your taste in terms of style, try to look past :)