-
-
Notifications
You must be signed in to change notification settings - Fork 164
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
[Question] Prisma + Interfaces? #1359
Comments
The general rule for interfaces is that object types need to by type-compatible with the type defined for an interface. Using a class for your interface is probably a bad starting place. What you can do is use a simpler interface type that only contains the common properties of the 2 tables interface Media {
title: string
}
const Media = builder.interfaceRef<Media>('Media')
Media.implement({
fields: (t) => ({
title: t.exposeString('title'),
poster: t.field({
type: Poster,
nullable: true,
// since we aren't defining a resolver here, movie and show need to implement the poster field as well
}),
})
})
const Movie = builder.prismaObject("Movie", {
interfaces: ["Media"], // Raises a TS error
fields: (t) => ({
poster: t.field({
type: Poster,
nullable: true,
select: { poster: true, posterThumb: true },
resolve: (movie) =>
movie.poster && movie.posterThumb
? new MediaPoster(posters.url(movie.poster), movie.posterThumb)
: null,
}),
})
}
)
builder.prismaObject("User", {
fields: (t) => ({
followedMedia: t.field({
type: [Media],
nullable: false,
select: {
followedMovies: {
select: {
movie: true,
},
},
followedShows: {
select: {
show: true,
},
},
},
resolve: async (user) => {
return [
// Adding brands will allow pothos to automatically determine the type during resolution
...Movie.addBrand(user.followedMovies),
...Show.addBrand(user.followedShows),
];
},
}) I've removed the type, because you can just query for |
Assume you have a domain that is modeled like so:
Media
is solely an API concept—Internally, Movie and Show are 2 separate tables, and there is no table that connects all of them to a single collection. So, with that in mind, we create theMedia
interface:And then have both Movie and Show implement that interface:
(Similar implementation on Show).
In this point, we already get a TS error saying the object shape must extend the interface - even though we have everything defined properly. If we ignore the error and run the code as-is, it still works, so let's try to move on for now.
We now have a query field on the type
User
calledfollowedMedia
, which queries the items the user follows. Let's define it in a naive way—But this raises a new error - the returned type, which is plain Prisma result objects, does not match the
Media
type.Makes sense - we couldn't really expect this to work as-is, but the docs don't mention how we can tackle this use-case.
prismaField
, which handles the mapping of the returned type to the GQL type, since the GQL type is a custom interface.new Movie(f.movie)
ornew Show(f.show)
since those types are internally generated by Pothos (so this only works for plain objects)poster
andposterThumb
fields into a singlePoster
object)So I'm wondering, what are the options here?
The text was updated successfully, but these errors were encountered: