Comments (21)
@mishushakov https://github.com/christopher-caldwell/garph-field-resolver-demo
If I left anything out, happy to clear it up! Thanks for taking the time to look.
from garph.
Great, will take a look!
from garph.
Will see on the weekend. Thanks for the reminder in any case!
from garph.
Sorry, I was a bit overwhelmed last weekend. I will you know when I have something 🙏
from garph.
@erickreutz I think you are missing the Infer
generic.
Taking your snippet, this works for me:
import { g, Infer, InferResolvers } from 'garph'
interface Context {
currentUser: Infer<typeof User>
}
const Profile = g.type('Profile', {
name: g.string(),
bio: g.string(),
})
const User = g.type('User', {
id: g.id(),
profile: g.ref(Profile),
})
const Query = g.type('Query', {
viewer: g.ref(User).optional(),
})
export const resolvers: InferResolvers<{ Query: typeof Query }, { context: Context }> = {
Query: {
viewer: (root, args, context, info) => {
return context.currentUser ?? null
},
},
}
I also don't think these issues are related. Again taking your example, my issue is that I'd like to define the User
in one file, and the Profile
in another. This isn't currently possible, unless you pass a singular reference to g
through function arguments in a factory pattern.
Edit: My bad, I was referencing a different issue.
from garph.
If it's helpful, I can make a sample repo showing the issue.
from garph.
You're welcome to contribute an example!
I'm also considering adding resolvers directly to the fields
from garph.
Also, could you try to do the same thing using SDL and graphql-codegen
and tell me whether the result matches what you expected? eg. Did you still have to use DeepOmit
there?
from garph.
Okay, I will put together an example.
I have the same issue with codegen, and it's the origin of the DeepOmit
lol. So it's not something that's lacking, more so trying to figure out the best way to make it work.
from garph.
If the behaviour is the same as with codegen, then it's "correctly" implemented on our side too. This doesn't mean we can't make improvements though 😄
Will check out your example once it's ready and see what we can do
Thanks
from garph.
Thanks!
from garph.
Any ideas?
from garph.
Thank you!
from garph.
I can try to contribute if you point me in the right direction.
from garph.
What I believe @christopher-caldwell is talking about is the issue and question I am running into as well.
As an example illustrated below - the profile doesn't exist on the object but is a derived field from the resolver so returning { id: string }
doesn't satisfy the expected return type { id: string, profile: Profile }
. What should we return here? I'd hope to not have to cast it.
const User = g.type("User", {
id: g.id(),
profile: g.ref(Profile)
});
const Profile = g.type("Profile", {
name: g.string(),
bio: g.string(),
});
const Query = g.type("Query", {
viewer: g.ref(User).optional()
});
const resolvers: InferResolvers<{ Query: typeof Query }, { context: Context, User: typeof User }> = {
Query: {
viewer: (root, args, context, info) => {
/*
TypeScript Error
Property 'profile' is missing in type 'User' but required in type '{ __typename?: "User" | undefined; id: string; profile: { __typename?: "Profile" | undefined; name: string; bio: string; }; }'
*/
return context.currentUser ?? null;
}
},
User: {
profile: async (parent, args, context, info) => {
return await db.findProfileByUserId(parent.id);
}
}
};
from garph.
@christopher-caldwell Hmm I'm not sure you are following then. currentUser
is not a graphql object. It's a record from the db representing the current user of the request. Illustrating an example that doesn't use the context results in the same issue.
const User = g.type('User', {
id: g.id(),
firstName: g.string(),
lastName: g.string(),
fullName: g.string(), // this is a resolved field
})
const Query = g.type('Query', {
viewer: g.ref(User).optional(),
})
export const resolvers: InferResolvers<{ Query: typeof Query, User: typeof User }, {}> = {
Query: {
viewer: (root, args, context, info) => {
// Property 'fullName' is missing in type '{ id: string; firstName: string; lastName: string; }' but required in type '{ __typename?: "User" | undefined; id: string; firstName: string; lastName: string; fullName: string; }
return {
id: '1',
firstName: 'John',
lastName: 'Doe',
}
},
},
User: {
fullName: (root, args, context, info) => {
return `${root.firstName} ${root.lastName}`;
}
}
}
Much like how your author
is not part of the Book
and is resolved fullName
is not part of User
but is resolved. As in my first example profile
is not part of User
but is resolved. We need some way to mark a field as being resolved something like g.resolved(g.string())
or g.string().resolved()
or define the resolvers inline with the type.
from garph.
@erickreutz Ahh okay! Yeah, I understand now. My bad.
Yeah having a way to mark the field as resolved by something else, exactly what you illustrate here, is my issue as well.
In a perfect world, if you marked a field as such (resolved or field level, whatever makes sense) and you did not declare it in the User
resolvers block, it should throw a TS error.
const User = g.type('User', {
id: g.id(),
firstName: g.string(),
lastName: g.string(),
fullName: g.string().fieldLevel() // whatever name makes sense
})
const resolvers: InferResolvers<{ Query: typeof Query, User: typeof User }, {}> = {
Query: {
viewer: '...'
},
User: {
// If this was omitted, but declared above as a field level resolver, TS should throw.
fullName: (root, args, context, info) => {
return `${root.firstName} ${root.lastName}`;
}
}
}
from garph.
Anything new here?
from garph.
Hey, just looked into this more deeply
Here are my findings:
- Currently, you cannot skip resolving a field unless you make it optional
- Resolving with a function, like in your data-loader example is now a valid pattern (since v0.5.2)
- Marking fields as "resolved" is a great Idea, I will totally consider this
Sorry for the wait 😁
from garph.
Here's a demo of upcoming omitResolver
. Once specified you can now skip resolving this value in the root resolver. You can combine it with InferStrict
Screen.Recording.2023-05-24.at.14.12.46.mov
Let me know if you have any feedback?
from garph.
.omitResolver
was added in 0.5.4
from garph.
Related Issues (20)
- Dedicated support for loaders HOT 9
- Input type should be able to specify a default value
- Automatic Filters HOT 1
- Automatic Pagination HOT 1
- Implementation-first API
- Semantics
- Drizzle Integration HOT 6
- Add auth examples
- Organizing complex projects
- Using garph's inbuilt relay schema builder types results in type errors. HOT 1
- Extending root-types HOT 4
- g.scalar does not support optional() HOT 6
- Type inference issues when organizing resolvers in separate files HOT 2
- Name collisions can result in somewhat obscure errors
- Support for self referential types HOT 2
- Augment resolved types with internal properties HOT 13
- how to insert more field after accrss paginatedList() HOT 1
- Make builtin types lazy HOT 2
- Inferred types for subscriptions is incorrect
- inputType type reference not work well (can only resolved with scalar type) HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from garph.