-
Notifications
You must be signed in to change notification settings - Fork 20
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
header in datasource-rest #49
Comments
I have the same problem :/ didReceiveResponse<TResult = any>(response: any, request: Request): Promise<any> {
const parent = super.didReceiveResponse.bind(this);
return new Promise(async (resolve) => {
const body = await parent<TResult>(response, request);
return resolve({
body,
req: request,
})
});
} But there are several problem in this solution :/ Isnt possíble to override a syncronous method with an asyncronous method (this explains why I returned a Promise, instead of use an async override) const { req, body } = await this.get<MyType>('/uri'); // Error
// I changed to
const { req, body } = await this.get('/uri');
return body as MyType; Too many problems, but works for me |
I refactored this and made a better solution. I created an interface like Axios response and overloaded the methods get, put, delete, patch and post. // Interface with response, like axios
interface ResponseInterface<T = any> {
data: T;
status: number;
headers: any;
request?: any;
}
class BaseAPIDataSource extends RESTDataSource {
didReceiveResponse(response: any, request: Request): Promise<any> {
// I'm getting some metrics here to prometheus
return this.formatResponse(response, request);
}
async formatResponse(response: any, request: Request): Promise<ResponseInterface> {
if (response.status >= 500) {
await super.didReceiveResponse(response, request);
}
const data = await this.parseBody(response);
return {
data,
status: response.status,
headers: response.headers,
request,
};
}
// Now I'm overloading the parent methods only changing the type response
protected async get<TResult = any, R = ResponseInterface<TResult>>(
path: string,
params?: URLSearchParamsInit,
init?: RequestInit,
): Promise<R> {
return super.get(path, params, init);
}
protected async put<TResult = any, R = ResponseInterface<TResult>>(
path: string,
body?: Body,
init?: RequestInit,
): Promise<R> {
return super.put(path, body, init);
}
protected async post<TResult = any, R = ResponseInterface<TResult>>(
path: string,
body?: Body,
init?: RequestInit,
): Promise<R> {
return super.post(path, body, init);
}
protected async patch<TResult = any, R = ResponseInterface<TResult>>(
path: string,
body?: Body,
init?: RequestInit,
): Promise<R> {
return super.patch(path, body, init);
}
protected async delete<TResult = any, R = ResponseInterface<TResult>>(
path: string,
params?: URLSearchParamsInit,
init?: RequestInit,
): Promise<R> {
return super.delete(path, params, init);
}
} The usage now is like Axios and the type validation works const { data, headers, status } = await this.get<MyCustomType>('/my/path', { page: 1 });
console.log(data, headers, status); |
Does overriding parseBody (which is protected) help here?
Or is that tough because parseBody doesn't know which particular API it is implementing? |
I can highly recommend to switch to your own DataSource and use axios instead of using the RESTDataSource. Its giving you more flexibility in the long run. |
If you need a more flexible data source you could try https://github.com/StarpTech/apollo-datasource-http. It's also listed here https://www.apollographql.com/docs/apollo-server/data/data-sources/ |
How can I read the header via apollo-datasource-rest from a response? I have a question posted on stackoverflow but no luck so far
https://stackoverflow.com/questions/60764956/read-header-from-response-with-apollo-datasource-rest
The text was updated successfully, but these errors were encountered: