How to add nested resolver to schema? - apollo

Let's say my query looks like this:
query {
post {
id
user { id, name }
}
}
And resolver map looks like this:
{
Query: {
post: myPostResolverFunc,
}
}
How I can add additional "nested" resolver for post.user?
I tried this but it does not work:
addResolveFunctionsToSchema(schema, {
Query: {
post: {
user: postUserResolveFunc,
},
}
});

You just have to write a resolver for your field. Assuming your schema is something like this :
type Post {
id: ID!,
user: User
}
type User {
id: ID!,
username: String!
}
type Query {
post(id: ID!): Post #assuming you want to request a simple post here
}
You can write resolvers like this :
addResolveFunctionsToSchema(schema, {
Post: {
user(root) {
return getUserById(root.user)
}
}
Query: {
post(root, args, context) {
return getPostById(args.id)
}
}
});

Related

How to delete cache record from Apollo GraphQL client with readQuery and writeQuery

The Apollo GraphQL team says that readQuery and writeQuery are good for 95% of the use cases. I am using useMutation and update and want to remove an item from a cache without having to call refetchQueries. My code is as follows:
const [deleteSpeaker] = useMutation(DELETE_SPEAKER, {
update(cache, { data: {deleteSpeaker}}) {
const { speakers} = cache.readQuery({query: GET_SPEAKERS});
cache.writeQuery({
query: GET_SPEAKERS,
data: { speakers: speakers.filter(speaker => speaker.id !== deleteSpeaker.id) }
});
},
});
What gets returned from readQuery leads me to think I should be filtering for speakers.datalist but when I do that, the cache does not update.
What is the correct way to update cache to reflect a removed record from the GET_SPEAKERS query.
export const DELETE_SPEAKER = gql`
mutation DeleteSpeaker($speakerId: Int!) {
deleteSpeaker(speakerId: $speakerId) {
id
first
last
favorite
}
}
`;
and GET_SPEAKERS
export const GET_SPEAKERS = gql`
query {
speakers {
datalist {
id
first
last
favorite
company
}
}
}
`;
reading apollo docs, this should be something lke:
const [deleteSpeaker] = useMutation(DELETE_SPEAKER, {
update(cache, { data: {deleteSpeaker}}) {
cache.modify({
id: cache.identify(deleteSpeaker.id),
fields: {
comments(existingSpeakerRefs, { readField }) {
return existingSpeakerRefs.filter(
speaker => deleteSpeaker.id !== readField('id', speakerRef)
);
},
},
});
},
});

How can i work with GraphQL Mutation?

how can i work with resolvers for mutations after i create type Mutations in graphql-yoga?
i've tried to create resolvers for mutations, but when i run in graph playground, i the code return error.
and here's my code:
const { GraphQLServer } = require('graphql-yoga')
// 1
const typeDefs = `
type Query {
users: [User!]!
user(id: ID!): User
}
type Mutation {
createUser(name: String!): User!
}
type User {
id: ID!
name: String!
}
`
// 2
const resolvers = {
Query: {
users: () => User,
},
Mutation: {
// WHAT SHOULD I WRITE IN HERE?
}
}
// 3
const server = new GraphQLServer({
typeDefs,
resolvers,
})
server.start(() => console.log(`Server is running on http://localhost:4000`))
if someone know how can i do for resolvers mutation, can shared with me?
thanks
Resolver for createUser can be defined as follows:
const resolvers = {
Query: {
// Query resolvers
},
Mutation: {
createUser: (parent, args) => {
// Business logic. Maybe save record in database
// Return created user. I am returning dummy data for now, so that you can test it in playground
return {id: 1, name: "John}
}
}
}
Finally it works for me.
i used this:
const resolvers = {
Query: {
users: () => User
},
Mutation: {
createUser: (source, {input}) => {
let newUser = [];
newUser.id = id;
newUser.name = input.name;
User.push(newUser);
return newUser;
}
}
}

How do I make graphql calls in series? react-apollo

I am composing 2 queries in a hoc with react-apollo. Here is my code:
let queries = compose(
graphql(gql`
query getUnitSubcategories($input: UnitSubcategorySearchInput) {
allUnitSubcategories(input:$input) {
edges {
node {
unitSubcategoryId
}
}
}
}
`, {
name: 'subcategories',
options: {
variables: {
input: {
activeFlag: true,
}
}
}
}),
graphql(gql`
query getFinancialTransactions($input: FinancialTransactionLineSearchInput) {
allFinancialTransactionLines(input: $input) {
pageInfo {
total
}
edges {
node {
financialTransaction {
financialTransactionId
}
}
}
}
}
`, {
name: 'financialTransactions',
options: {
variables: {
input: {
unitSubcategories: [
....
]
}
}
}
})
);
You can see that I am getting the unitSubcategories in the first query and they need to be passed to the second query. So I don't want to kick off the second query until I have a result from my first query. What is the best way to do this?
You'll want to use the skip config. See https://www.apollographql.com/docs/react/basics/queries.html#graphql-skip
In your example, you might want to define the skip config in the second query something like this:
{
name: 'financialTransactions',
skip: ({ unitSubcategories }) => !unitSubcategories,
options: ({ unitSubcategories }) => ({
variables: {
input: {
unitSubcategories
}
}
})
}
where you only want the second query to run after you've received the result from the first query. And then use options as a function so you can compute them from props.

Add Ember Data query helper method

I'm using Ember API with a JSON API backend. The API accepts filters like this:
/users?filter[simple][name]=John
Right now, whenever I want to make a query, I'm doing this:
this.store.query('users', {
filter: {
simple: {
name: 'John'
}
}
});
It would be nice to avoid this verbosity by adding a helper function that works like this:
this.store.simpleQuery('users', { name: 'John' });
That function would pass its arguments directly to query(), just wrapping the query in { filter: { simple: ... } }.
Is this possible? How do I do this?
Well what is stopping you from creating your own method in the adapter to do exactly that?
// ... your adapter code
simpleQuery: function(modelName, query) {
return this.store.query('users', {
filter: {
simple: {
name: 'John'
}
}
});
}
// ...
You need to extend the default store. Add the following to app/services/store.js
import DS from 'ember-data';
export default DS.Store.extend({
simpleQuery(modelName, query) {
return this.query(modelName, {
filter: { simple: query }
});
},
simpleQueryRecord(modelName, query) {
return this.queryRecord(modelName, {
filter: { simple: query }
});
}
});
And you'll be able to do this:
this.store.simpleQuery('users', { name: 'John' });
this.store.simpleQueryRecord('users', { email: 'john#example.com' });

How to query only with included models?

I have a query that looks like this:
User.find({
include: {
relation: 'Comment',
scope: {
where: {
text: {
like: '%some text'
}
}
}
}
}, function (err, users) {
...
})
Everything works great, but i want to be able to query only the users that commented "some text", like a inner join.
How can i do that?