[2.0] Allow dynamic configuration of data sources#1277
Conversation
|
I personally would get rid of |
|
@danilobuerger I agree with your feedback and simplified the API. I removed
That means you can now do: willSendRequest(request: RequestOptions) {
if (request.method === 'GET') {
request.params.set('api_key', this.context.token);
} else {
request.headers.set('Authorization', this.context.token);
}
}What do you think? I like allowing |
|
You are probably right, I can't think of a good one. For me I would just use a datasource per microservice thus not needing to access the path. Promise might be enough! |
|
@danilobuerger I'm still bike shedding over this. It seems allowing I was thinking a more straightforward solution might be to introduce a The default implementation simply creates a new I think that would turn your original example into: async resolveURL(request: RequestOptions) {
if (!this.baseURL) {
const addresses = await resolveSrv(request.path.split("/")[1] + ".service.consul");
this.baseURL = addresses[0];
}
return super.resolveURL(request);
}But you could also do something more complicated and circumvent the superclass implementation completely. Not sure if this makes sense, but you could store the complete list of Maybe I'm overcomplicating this. What do you think? |
|
I think that change to I don't see an issue with Edit: Going back to Also read the new replies, and I think I understand the concerns you have about baseURL being a promise. Computing the URL on every request does seem excessive, especially if it involves another tick of the event loop. I don't know what the best solution for this would be. |
|
@Saeris The issue I saw with allowing Setting So you would do: async resolveURL(request: RequestOptions) {
if (!this.baseURL) {
const addresses = await resolveSrv(request.path.split("/")[1] + ".service.consul");
this.baseURL = addresses[0];
}
return super.resolveURL(request);
}Instead of: baseURL = async (request: RequestOptions) => {
const addresses = await resolveSrv(request.path.split("/")[1] + ".service.consul");
return addresses[0];
}What do you think? |
|
|
|
A bit late now, but why is |
|
@danilobuerger Although technically you could do everything in I see Implementing |
|
Ok, sure I can see that. |
|
@danilobuerger An alternative might be to allow |
|
Hmm, all speculation at that point. Maybe lets just leave it as is now and see how other people feel about it when they start using it? |
|
Yeah, you're right, I know I'm prone to bikeshedding :) |
|
Hey @martijnwalraven looks great! Thanks for picking up on this and extending the Datasources. Just out of bike-shedding interest, would there be a way (in theory) to have a method that doesn't require calling I am not sure if this would be a good idea but if the base class's let url = this.resolveUrl ? await this.resolveURL(options) : undefined;
url = await this.sanitizeURL(options);I know this ^ won't work but you get what I mean I guess :) |
|
You don't have to call super in resolveURL if you override it. Actually, if you override resolveURL you will most likely not want to call super. |
This PR adds callbacks to
RESTDataSourcethat allow for asynchronous and dynamic configuration of data sources. It addresses #1181 and #1238.It allows a data source to specify
baseURL,defaultsanddefaultParamseither as simple properties, properties that return aPromise, or as a function that takesRequestOptionsand returns either a value or aPromise.So you could implement the example from #1181 (comment) as follows:
And you can specify default params as discussed in #1238:
So
getFoo(1)would result in a request to'https://api.example.com/foo?api_key=secret&a=1'.I also added a
defaultscallback, which allows you to specify default fetch options:One worry is that there is overlap between
defaultsandwillSendRequest. You could use both to set headers for example:vs:
It seems this could get confusing.
Also, I think ideally we could get rid of
defaultParamsand rely onwillSendRequestfor this as well, but unfortunatelyrequest.urlis a read-only string, not aURL. So you can't do:One option would be to pass in
RequestInitandURLtowillSendRequestinstead ofRequest, but that also feels awkward.