I have apollo-server setup which have:
To get cars (model and engine data), firstly I need to fetch cars models (hardcoded), and then, based on these models, fetch engine information.
I have separate queries for PetrolEngine and DieselEngine.
Is it possible to make apollo understand somehow to use these queries (Query.petrolEngine, Query.dieselEngine) and distinguish them while working with 'Car.engine' field that gets model name.
import { ApolloServer } from '@apollo/server';
import { startStandaloneServer } from '@apollo/server/standalone';
const typeDefs = `#graphql
type Car {
model: String
engine: CarEngine
}
union CarEngine = DieselEngine | PetrolEngine
type DieselEngine {
capacity: Float
dieselType: String
}
type PetrolEngine {
capacity: Float
petrolType: String
}
type Query {
cars: [Car]
dieselEngine: DieselEngine
petrolEngine: PetrolEngine
}
`;
const engines = {
bmw: {capacity: 2.0, dieselType: 'L'},
fiat: {capacity: 1.6, petrolType: '95'},
}
const resolvers = {
Query: {
cars: () => [{ model: 'bmw' }, { model: 'fiat' }],
dieselEngine: (carModel) => { engines[carModel] },
petrolEngine: (carModel) => { engines[carModel] },
},
Car: {
engine: (parent) => {
}
},
CarEngine: {
__resolveType: (obj) => {
console.log('resolving type for ', obj);
if (obj?.dieselType) return 'DieselEngine';
else return 'PetrolEngine';
}
}
};
const server = new ApolloServer({
typeDefs,
resolvers,
});
const { url } = await startStandaloneServer(server);
A useful pattern is just to define functions that can be applied to multiple resolvers and/or queries.
const getEngine = ({model}) => engines[model]
Then you can do something like:
const resolvers = {
Query: {
cars: () => [{ model: 'bmw' }, { model: 'fiat' }],
dieselEngine: getEngine,
petrolEngine: getEngine,
},
Car: {
engine: getEngine,
},
CarEngine: {
__resolveType: (obj) => {
console.log('resolving type for ', obj);
if (obj?.dieselType) return 'DieselEngine';
else return 'PetrolEngine';
}
dieselType: (parent) => parent.dieselType,
petrolType: (parent) => parent.petrolType,
}
};
I should add that your petrolEngine
and dieselEngine
queries make no sense as written. Firstly in your typeDefs these queries have no variables even though you have a carModel
variable in your resolver code. Secondly, if you wanted to find out what engine a car model had you could just have a getEngine
query that took the carModel
as input and returned whatever engine it had, either diesel or petrol. Having a query specific to the engine type assumes that the carModel variable has that kind of engine.