Skip to content
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

The wrapper inefficiently takes 2.5s for each query by repeatedly calling makePromise #13

Open
ChristianIvicevic opened this issue Aug 19, 2019 · 2 comments

Comments

@ChristianIvicevic
Copy link

After trying out your library we discovered that your call to makePromise is highly inefficient since it takes 2.5s for each query. It gets especially since it takes multiples of 2.5s for each sub-query.

const [error, response] = await to(makePromise(execute(link, operation)));

You should create a single client that you persist through multiple calls to the very same endpoint. That's why we moved to a custom wrapper that create such a single client.

@Enalmada
Copy link

@ChristianIvicevic Could you opensource or gist your custom wrapper?

@ChristianIvicevic
Copy link
Author

We just ended up with two things. First of all our small custom GraphQLDataSource class:

import ApolloClient, {QueryOptions} from 'apollo-boost';
import fetch from 'node-fetch';

export abstract class GraphQLDataSource {
	protected client: ApolloClient<unknown>;

	protected constructor(uri?: string) {
		this.client = new ApolloClient({
			uri,
			fetch: (fetch as unknown) as GlobalFetch['fetch'],
			headers: {
				'Cache-Control': 'no-cache'
			}
		});
	}

	protected query<TResponse, TVariables>(options: QueryOptions<TVariables>) {
		return this.client.query<TResponse, TVariables>(options);
	}
}

The datasources look as follows:

export class MasterDataGraphQLApi extends GraphQLDataSource {
	public constructor() {
		super(process.env.MASTER_DATA_GQL_ENDPOINT);
	}

	public async getProjects(offset: number, first: number) {
		try {
			const response = await this.query<ProjectsQuery, ProjectsQueryVariables>({
				query: GET_PROJECTS,
				variables: {offset, first}
			});
			return response.data.projects.page;
		} catch (error) {
			console.error(error);
		}
	}
	// ...
}

Furthermore when injecting the datasources keep in mind to use the same instances and not creating them with each call:

import {ApolloServer, IResolvers} from 'apollo-server-express';

const masterDataApi = new MasterDataGraphQLApi();
const dataQueryApi = new DataQueryGraphQLApi();

const dataSources = () => ({
	masterDataApi,
	dataQueryApi,
});

const server = new ApolloServer({
	typeDefs: schema,
	resolvers: (resolvers as unknown) as IResolvers,
	dataSources: dataSources as <T extends object>() => Record<string, T>,
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants