I am using Elixir/Phoenix with Absinthe to define a federated graph in Apollo. I have looked through the Odyssey Voyage I course but cant seem to piece together what I need. Here is my scenario:
I have two services (or subgraphs). One is the ProjectLocation subgraph and the other is the Inspection subgraph. A ProjectLocation can have 1 to many Inspections. What I need is to query a ProjectLocation and get it back with all of it's Inspections based on inspection parameters. I have my modules separated out into types, mutations, queries, resolvers, and then import them all into one schema file.
ProjectLocation Subgraph Type
defmodule MyProject.Schema.Types.ProjectLocation do
use Absinthe.Schema.Notation
object :project_location do
field :id, :id
field :project_id, :id
field :address, :string
end
input_object :input_project_location_params do
field :id, :id
field :project_id, :id
field :address, :string
end
end
ProjectLocation Subgraph Query
defmodule MyProject.Schema.Queries.ProjectLocation do
use Absinthe.Schema.Notation
alias MyProject.Schema.Resolvers
object :project_location_queries do
@desc "Find ProjectLocation"
field :project_location, type: :project_location do
arg(:project_location_id, non_null(:id))
resolve(&Resolvers.ProjectLocation.get_project_location/3)
end
end
end
Inspection Subgraph Type
defmodule MyInspectionProject.Schema.Types.Inspection do
use Absinthe.Schema.Notation
object :inspection do
field :id, :id
field :project_id, :id
field :inspection_location, :id //This is the project location id (bad naming on my part)
field :status, :string
end
@desc "Inspection"
input_object :input_inspection_params do
field :id, :id
field :project_id, :id
field :inspection_location, :id
field :status, :string
end
end
Inspection Subgraph Query
defmodule MyInspectionProject.Schema.Queries.Inspection do
use Absinthe.Schema.Notation
alias MyInspectionProject.Schema.Resolvers
object :inspection_queries do
@desc "Find Inspection"
field :inspection, type: :inspection do
arg(:inspection, non_null(:input_inspection_params))
resolve(&Resolvers.Inspection.get_inspection/3)
end
end
end
Using a React front end we would write the query for a project location like this:
const GET_PROJECT_LOCATIONS = gql`
query ProjectLocations($projectId: ID!) {
projectLocations(projectId: $projectId) {
id
projectId
address
}
}
`;
My question I guess is how do I set up the types and write the query to preload and query the inspections as a "subquery?" Is it as simple as setting up an Inspection type in the ProjectLocation subgraph and writing the query somewhere along the lines of this?
const GET_PROJECT_LOCATIONS = gql`
query ProjectLocations($projectId: ID!) {
projectLocations(projectId: $projectId) {
id
projectId
address
inspection($status: STRING){
id
project_id
inspection_location
status
}
}
}
`;
If so what would the variables object look like to pass into this GraphQL call. Also forgot to mention I'm using the useLazyQuery hook from the Apollo Client library in React.
That graphql would be valid if the inspection
statuswas also an arg to the root query (2nd arg, after projectID). See here for an example: https://elixirforum.com/t/why-do-you-have-to-re-declare-types-in-graphql-queries-when-you-use-variables/52723/10It would look like this for you:
Also add an
:inspectionfield in yourproject_locationobject definition. There you can handle thestatusarg by writing the field with a resolve function. It will look like this: