-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[2.0] Allow dynamic configuration of data sources #1277
[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
RESTDataSource
that allow for asynchronous and dynamic configuration of data sources. It addresses #1181 and #1238.It allows a data source to specify
baseURL
,defaults
anddefaultParams
either as simple properties, properties that return aPromise
, or as a function that takesRequestOptions
and 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
defaults
callback, which allows you to specify default fetch options:One worry is that there is overlap between
defaults
andwillSendRequest
. 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
defaultParams
and rely onwillSendRequest
for this as well, but unfortunatelyrequest.url
is a read-only string, not aURL
. So you can't do:One option would be to pass in
RequestInit
andURL
towillSendRequest
instead ofRequest
, but that also feels awkward.