Summary
I have two example PostGraphile services: a media service having a movie
entity and a video service having a video
entity. The movie entity stores the ID of the video. The federation service should allow to query movie->video->title.
Additional context
Using latest PostGraphile in library version and latest version of the graphile/federation library.
I am using the express way to include PostGraphile in the minimal version for each service.
I am following the guide on https://www.apollographql.com/docs/federation/quickstart/ to add both services to the federation service. This works all fine - I can get in one query both the details from the media and video service (but cannot resolve movie --> video --> fields).
Media service
CREATE TABLE public.movies (
id INT NOT NULL PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
title text NOT NULL,
description text,
video_id INT
);
INSERT INTO public.movies (title, description, video_id) VALUES
('Avatar', 'Jake, who is paraplegic, replaces his twin on the Na''vi inhabited Pandora for a corporate mission. After the natives accept him as one of their own, he must decide where his loyalties lie.', 1),
('Black Widow', 'Natasha Romanoff, aka Black Widow, confronts the darker parts of her ledger when a dangerous conspiracy with ties to her past arises. Pursued by a force that will stop at nothing to bring her down, Natasha must deal with her history as a spy, and the broken relationships left in her wake long before she became an Avenger.', 2),
('The Lord of the Rings: The Two Towers', 'Frodo and Sam arrive in Mordor with the help of Gollum. A number of new allies join their former companions to defend Isengard as Saruman launches an assault from his domain.', 3);
Video service
CREATE TABLE public.videos (
id INT NOT NULL PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
title text NOT NULL,
video_url text
);
INSERT INTO public.videos (id, title, video_url) VALUES
(1, 'Avatar Trailer', 'https://www.youtube.com/watch?v=6ziBFh3V1aM'),
(2, 'Black Widow Trailer', 'https://www.youtube.com/watch?v=ybji16u608U'),
(3, 'The Lord of the Rings: The Two Towers Trailer', 'https://www.youtube.com/watch?v=Y4neBR0h39c');
The _entities
query is working nicely when I run it directly against the video service.
query videos {
_entities(representations: [
{
__typename: "Video",
nodeId: "WyJ2aWRlb3MiLDFd"
}]) {
... on Video {
id
nodeId
title
videoUrl
}
}
}
Question
I tried multiple different approaches with makeExtendSchemaPlugin
and others - how can I correctly update the Movie
entity to have a Video
reference?
In the end I (think I) need the following in the generated schema:
type Movie implements Node @key(fields: "nodeId") {
id: Int!
title: String!
description: String
nodeId: ID!
videoId: Int
# this video here - should be resolved via nodeId (or directly the ID if that is possible)
video: Video
}
extend type Video @key(fields: "nodeId") {
nodeId: ID! @external
}
My failed attempt with a plugin on the media side:
const { makeExtendSchemaPlugin, gql } = require("graphile-utils");
const ExtendPlugin = makeExtendSchemaPlugin(() => {
return {
typeDefs: gql`
# hack - must be later removed
type Video {
DoNotUseThisProperty: String
}
# This is how it should really look like - or use the nodeId:
extend type Video @key(fields: "id") {
id: Int! @external
}
extend type Movie {
video: Video
}
`,
resolvers: {
Movie: {
video: async (movie) => {
console.log(movie);
return {
id: movie.videoId,
};
},
},
},
};
});
module.exports = ExtendPlugin;
With the above plugin the video service does not correctly receive any request to resolve the video
entity within the video service.
The following query against the federation service would be my goal - the allVideos
is working fine and allMovies
is working fine if I remove the video
sub-object query:
query ExampleQuery {
allMovies {
nodes {
id
videoId
title
video {
id
title
nodeId
}
}
}
allVideos {
nodes {
id
title
videoUrl
}
}
}
Thanks for any suggestions or ideas.