Skip to content

Instantly share code, notes, and snippets.

@JofArnold
Last active February 24, 2025 14:59
Show Gist options
  • Save JofArnold/a3b16bc2ac1cb266989c70acede462da to your computer and use it in GitHub Desktop.
Save JofArnold/a3b16bc2ac1cb266989c70acede462da to your computer and use it in GitHub Desktop.
Generating GraphQL queries from schemas

Uses Neo4j example graph with Apollo Server.

Passed the full introspected schema to Claude Chat.

First reply used an invalid filter but asked it to look at PersonWhere again and it worked

Prompt

Using the following schema, create a graphql query that gets me all the people who've worked in movies alongside Keanu Reeves

Then to fix the where check

You have made a mistake. Double-check your filter against PersonWhere

"""
Indicates exactly one field must be supplied and this field must not be `null`.
"""
directive @oneOf on INPUT_OBJECT
type Query {
movies(where: MovieWhere, limit: Int, offset: Int, sort: [MovieSort!], options: MovieOptions @deprecated(reason: "Query options argument is deprecated, please use pagination arguments like limit, offset and sort instead.")): [Movie!]!
moviesConnection(first: Int, after: String, where: MovieWhere, sort: [MovieSort!]): MoviesConnection!
moviesAggregate(where: MovieWhere): MovieAggregateSelection!
people(where: PersonWhere, limit: Int, offset: Int, sort: [PersonSort!], options: PersonOptions @deprecated(reason: "Query options argument is deprecated, please use pagination arguments like limit, offset and sort instead.")): [Person!]!
peopleConnection(first: Int, after: String, where: PersonWhere, sort: [PersonSort!]): PeopleConnection!
peopleAggregate(where: PersonWhere): PersonAggregateSelection!
}
type Mutation {
createMovies(input: [MovieCreateInput!]!): CreateMoviesMutationResponse!
deleteMovies(where: MovieWhere, delete: MovieDeleteInput): DeleteInfo!
updateMovies(where: MovieWhere, update: MovieUpdateInput): UpdateMoviesMutationResponse!
createPeople(input: [PersonCreateInput!]!): CreatePeopleMutationResponse!
deletePeople(where: PersonWhere, delete: PersonDeleteInput): DeleteInfo!
updatePeople(where: PersonWhere, update: PersonUpdateInput): UpdatePeopleMutationResponse!
}
"""An enum for sorting in either ascending or descending order."""
enum SortDirection {
"""Sort by field values in ascending order."""
ASC
"""Sort by field values in descending order."""
DESC
}
"""
Information about the number of nodes and relationships created during a create mutation
"""
type CreateInfo {
nodesCreated: Int!
relationshipsCreated: Int!
}
type CreateMoviesMutationResponse {
info: CreateInfo!
movies: [Movie!]!
}
type CreatePeopleMutationResponse {
info: CreateInfo!
people: [Person!]!
}
"""
Information about the number of nodes and relationships deleted during a delete mutation
"""
type DeleteInfo {
nodesDeleted: Int!
relationshipsDeleted: Int!
}
type Movie {
title: String
actorsAggregate(where: PersonWhere, directed: Boolean = true @deprecated(reason: "The directed argument is deprecated, and the direction of the field will be configured in the GraphQL server")): MoviePersonActorsAggregationSelection
actors(where: PersonWhere, limit: Int, offset: Int, sort: [PersonSort!], options: PersonOptions @deprecated(reason: "Query options argument is deprecated, please use pagination arguments like limit, offset and sort instead."), directed: Boolean = true @deprecated(reason: "The directed argument is deprecated, and the direction of the field will be configured in the GraphQL server")): [Person!]!
actorsConnection(where: MovieActorsConnectionWhere, first: Int, after: String, directed: Boolean = true @deprecated(reason: "The directed argument is deprecated, and the direction of the field will be configured in the GraphQL server"), sort: [MovieActorsConnectionSort!]): MovieActorsConnection!
}
type MovieActorsConnection {
edges: [MovieActorsRelationship!]!
totalCount: Int!
pageInfo: PageInfo!
}
type MovieActorsRelationship {
cursor: String!
node: Person!
}
type MovieAggregateSelection {
count: Int!
title: StringAggregateSelection!
}
type MovieEdge {
cursor: String!
node: Movie!
}
type MoviePersonActorsAggregationSelection {
count: Int!
node: MoviePersonActorsNodeAggregateSelection
}
type MoviePersonActorsNodeAggregateSelection {
name: StringAggregateSelection!
}
type MoviesConnection {
totalCount: Int!
pageInfo: PageInfo!
edges: [MovieEdge!]!
}
"""Pagination information (Relay)"""
type PageInfo {
hasNextPage: Boolean!
hasPreviousPage: Boolean!
startCursor: String
endCursor: String
}
type PeopleConnection {
totalCount: Int!
pageInfo: PageInfo!
edges: [PersonEdge!]!
}
type Person {
name: String
moviesAggregate(where: MovieWhere, directed: Boolean = true @deprecated(reason: "The directed argument is deprecated, and the direction of the field will be configured in the GraphQL server")): PersonMovieMoviesAggregationSelection
movies(where: MovieWhere, limit: Int, offset: Int, sort: [MovieSort!], options: MovieOptions @deprecated(reason: "Query options argument is deprecated, please use pagination arguments like limit, offset and sort instead."), directed: Boolean = true @deprecated(reason: "The directed argument is deprecated, and the direction of the field will be configured in the GraphQL server")): [Movie!]!
moviesConnection(where: PersonMoviesConnectionWhere, first: Int, after: String, directed: Boolean = true @deprecated(reason: "The directed argument is deprecated, and the direction of the field will be configured in the GraphQL server"), sort: [PersonMoviesConnectionSort!]): PersonMoviesConnection!
}
type PersonAggregateSelection {
count: Int!
name: StringAggregateSelection!
}
type PersonEdge {
cursor: String!
node: Person!
}
type PersonMovieMoviesAggregationSelection {
count: Int!
node: PersonMovieMoviesNodeAggregateSelection
}
type PersonMovieMoviesNodeAggregateSelection {
title: StringAggregateSelection!
}
type PersonMoviesConnection {
edges: [PersonMoviesRelationship!]!
totalCount: Int!
pageInfo: PageInfo!
}
type PersonMoviesRelationship {
cursor: String!
node: Movie!
}
type StringAggregateSelection {
shortest: String
longest: String
}
"""
Information about the number of nodes and relationships created and deleted during an update mutation
"""
type UpdateInfo {
nodesCreated: Int!
nodesDeleted: Int!
relationshipsCreated: Int!
relationshipsDeleted: Int!
}
type UpdateMoviesMutationResponse {
info: UpdateInfo!
movies: [Movie!]!
}
type UpdatePeopleMutationResponse {
info: UpdateInfo!
people: [Person!]!
}
input MovieActorsAggregateInput {
count_EQ: Int
count_LT: Int
count_LTE: Int
count_GT: Int
count_GTE: Int
count: Int @deprecated(reason: "Please use the explicit _EQ version")
AND: [MovieActorsAggregateInput!]
OR: [MovieActorsAggregateInput!]
NOT: MovieActorsAggregateInput
node: MovieActorsNodeAggregationWhereInput
}
input MovieActorsConnectFieldInput {
where: PersonConnectWhere
"""
Whether or not to overwrite any matching relationship with the new properties.
"""
overwrite: Boolean! = true @deprecated(reason: "The overwrite argument is deprecated and will be removed")
connect: [PersonConnectInput!]
}
input MovieActorsConnectionSort {
node: PersonSort
}
input MovieActorsConnectionWhere {
AND: [MovieActorsConnectionWhere!]
OR: [MovieActorsConnectionWhere!]
NOT: MovieActorsConnectionWhere
node: PersonWhere
}
input MovieActorsCreateFieldInput {
node: PersonCreateInput!
}
input MovieActorsDeleteFieldInput {
where: MovieActorsConnectionWhere
delete: PersonDeleteInput
}
input MovieActorsDisconnectFieldInput {
where: MovieActorsConnectionWhere
disconnect: PersonDisconnectInput
}
input MovieActorsFieldInput {
connect: [MovieActorsConnectFieldInput!]
create: [MovieActorsCreateFieldInput!]
}
input MovieActorsNodeAggregationWhereInput {
AND: [MovieActorsNodeAggregationWhereInput!]
OR: [MovieActorsNodeAggregationWhereInput!]
NOT: MovieActorsNodeAggregationWhereInput
name_AVERAGE_LENGTH_EQUAL: Float
name_LONGEST_LENGTH_EQUAL: Int
name_SHORTEST_LENGTH_EQUAL: Int
name_AVERAGE_LENGTH_GT: Float
name_LONGEST_LENGTH_GT: Int
name_SHORTEST_LENGTH_GT: Int
name_AVERAGE_LENGTH_GTE: Float
name_LONGEST_LENGTH_GTE: Int
name_SHORTEST_LENGTH_GTE: Int
name_AVERAGE_LENGTH_LT: Float
name_LONGEST_LENGTH_LT: Int
name_SHORTEST_LENGTH_LT: Int
name_AVERAGE_LENGTH_LTE: Float
name_LONGEST_LENGTH_LTE: Int
name_SHORTEST_LENGTH_LTE: Int
}
input MovieActorsUpdateConnectionInput {
node: PersonUpdateInput
}
input MovieActorsUpdateFieldInput {
where: MovieActorsConnectionWhere
connect: [MovieActorsConnectFieldInput!]
disconnect: [MovieActorsDisconnectFieldInput!]
create: [MovieActorsCreateFieldInput!]
update: MovieActorsUpdateConnectionInput
delete: [MovieActorsDeleteFieldInput!]
}
input MovieConnectInput {
actors: [MovieActorsConnectFieldInput!]
}
input MovieConnectWhere {
node: MovieWhere!
}
input MovieCreateInput {
title: String
actors: MovieActorsFieldInput
}
input MovieDeleteInput {
actors: [MovieActorsDeleteFieldInput!]
}
input MovieDisconnectInput {
actors: [MovieActorsDisconnectFieldInput!]
}
input MovieOptions {
limit: Int
offset: Int
"""
Specify one or more MovieSort objects to sort Movies by. The sorts will be applied in the order in which they are arranged in the array.
"""
sort: [MovieSort!]
}
"""
Fields to sort Movies by. The order in which sorts are applied is not guaranteed when specifying many fields in one MovieSort object.
"""
input MovieSort {
title: SortDirection
}
input MovieUpdateInput {
title: String @deprecated(reason: "Please use the explicit _SET field")
title_SET: String
actors: [MovieActorsUpdateFieldInput!]
}
input MovieWhere {
title: String @deprecated(reason: "Please use the explicit _EQ version")
title_EQ: String
title_IN: [String]
title_CONTAINS: String
title_STARTS_WITH: String
title_ENDS_WITH: String
OR: [MovieWhere!]
AND: [MovieWhere!]
NOT: MovieWhere
"""Return Movies where all of the related People match this filter"""
actors_ALL: PersonWhere
"""Return Movies where none of the related People match this filter"""
actors_NONE: PersonWhere
"""Return Movies where one of the related People match this filter"""
actors_SINGLE: PersonWhere
"""Return Movies where some of the related People match this filter"""
actors_SOME: PersonWhere
"""
Return Movies where all of the related MovieActorsConnections match this filter
"""
actorsConnection_ALL: MovieActorsConnectionWhere
"""
Return Movies where none of the related MovieActorsConnections match this filter
"""
actorsConnection_NONE: MovieActorsConnectionWhere
"""
Return Movies where one of the related MovieActorsConnections match this filter
"""
actorsConnection_SINGLE: MovieActorsConnectionWhere
"""
Return Movies where some of the related MovieActorsConnections match this filter
"""
actorsConnection_SOME: MovieActorsConnectionWhere
actorsAggregate: MovieActorsAggregateInput
}
input PersonConnectInput {
movies: [PersonMoviesConnectFieldInput!]
}
input PersonConnectWhere {
node: PersonWhere!
}
input PersonCreateInput {
name: String
movies: PersonMoviesFieldInput
}
input PersonDeleteInput {
movies: [PersonMoviesDeleteFieldInput!]
}
input PersonDisconnectInput {
movies: [PersonMoviesDisconnectFieldInput!]
}
input PersonMoviesAggregateInput {
count_EQ: Int
count_LT: Int
count_LTE: Int
count_GT: Int
count_GTE: Int
count: Int @deprecated(reason: "Please use the explicit _EQ version")
AND: [PersonMoviesAggregateInput!]
OR: [PersonMoviesAggregateInput!]
NOT: PersonMoviesAggregateInput
node: PersonMoviesNodeAggregationWhereInput
}
input PersonMoviesConnectFieldInput {
where: MovieConnectWhere
"""
Whether or not to overwrite any matching relationship with the new properties.
"""
overwrite: Boolean! = true @deprecated(reason: "The overwrite argument is deprecated and will be removed")
connect: [MovieConnectInput!]
}
input PersonMoviesConnectionSort {
node: MovieSort
}
input PersonMoviesConnectionWhere {
AND: [PersonMoviesConnectionWhere!]
OR: [PersonMoviesConnectionWhere!]
NOT: PersonMoviesConnectionWhere
node: MovieWhere
}
input PersonMoviesCreateFieldInput {
node: MovieCreateInput!
}
input PersonMoviesDeleteFieldInput {
where: PersonMoviesConnectionWhere
delete: MovieDeleteInput
}
input PersonMoviesDisconnectFieldInput {
where: PersonMoviesConnectionWhere
disconnect: MovieDisconnectInput
}
input PersonMoviesFieldInput {
connect: [PersonMoviesConnectFieldInput!]
create: [PersonMoviesCreateFieldInput!]
}
input PersonMoviesNodeAggregationWhereInput {
AND: [PersonMoviesNodeAggregationWhereInput!]
OR: [PersonMoviesNodeAggregationWhereInput!]
NOT: PersonMoviesNodeAggregationWhereInput
title_AVERAGE_LENGTH_EQUAL: Float
title_LONGEST_LENGTH_EQUAL: Int
title_SHORTEST_LENGTH_EQUAL: Int
title_AVERAGE_LENGTH_GT: Float
title_LONGEST_LENGTH_GT: Int
title_SHORTEST_LENGTH_GT: Int
title_AVERAGE_LENGTH_GTE: Float
title_LONGEST_LENGTH_GTE: Int
title_SHORTEST_LENGTH_GTE: Int
title_AVERAGE_LENGTH_LT: Float
title_LONGEST_LENGTH_LT: Int
title_SHORTEST_LENGTH_LT: Int
title_AVERAGE_LENGTH_LTE: Float
title_LONGEST_LENGTH_LTE: Int
title_SHORTEST_LENGTH_LTE: Int
}
input PersonMoviesUpdateConnectionInput {
node: MovieUpdateInput
}
input PersonMoviesUpdateFieldInput {
where: PersonMoviesConnectionWhere
connect: [PersonMoviesConnectFieldInput!]
disconnect: [PersonMoviesDisconnectFieldInput!]
create: [PersonMoviesCreateFieldInput!]
update: PersonMoviesUpdateConnectionInput
delete: [PersonMoviesDeleteFieldInput!]
}
input PersonOptions {
limit: Int
offset: Int
"""
Specify one or more PersonSort objects to sort People by. The sorts will be applied in the order in which they are arranged in the array.
"""
sort: [PersonSort!]
}
"""
Fields to sort People by. The order in which sorts are applied is not guaranteed when specifying many fields in one PersonSort object.
"""
input PersonSort {
name: SortDirection
}
input PersonUpdateInput {
name: String @deprecated(reason: "Please use the explicit _SET field")
name_SET: String
movies: [PersonMoviesUpdateFieldInput!]
}
input PersonWhere {
name: String @deprecated(reason: "Please use the explicit _EQ version")
name_EQ: String
name_IN: [String]
name_CONTAINS: String
name_STARTS_WITH: String
name_ENDS_WITH: String
OR: [PersonWhere!]
AND: [PersonWhere!]
NOT: PersonWhere
"""Return People where all of the related Movies match this filter"""
movies_ALL: MovieWhere
"""Return People where none of the related Movies match this filter"""
movies_NONE: MovieWhere
"""Return People where one of the related Movies match this filter"""
movies_SINGLE: MovieWhere
"""Return People where some of the related Movies match this filter"""
movies_SOME: MovieWhere
"""
Return People where all of the related PersonMoviesConnections match this filter
"""
moviesConnection_ALL: PersonMoviesConnectionWhere
"""
Return People where none of the related PersonMoviesConnections match this filter
"""
moviesConnection_NONE: PersonMoviesConnectionWhere
"""
Return People where one of the related PersonMoviesConnections match this filter
"""
moviesConnection_SINGLE: PersonMoviesConnectionWhere
"""
Return People where some of the related PersonMoviesConnections match this filter
"""
moviesConnection_SOME: PersonMoviesConnectionWhere
moviesAggregate: PersonMoviesAggregateInput
}
query FindKeanuCostars {
# First find Keanu Reeves
keanusMovies: people(where: { name_EQ: "Keanu Reeves" }, limit: 1) {
name
# Get all movies Keanu has acted in
movies(sort: [{ title: ASC }], limit: 100) {
title
# For each movie, get all actors (will include Keanu)
actors(sort: [{ name: ASC }], limit: 100) {
name
}
}
}
# As an alternative approach, we can also get all people who appeared in movies
# where Keanu appeared, using a nested filter
costars: people(
where: {
# Exclude Keanu himself - using NOT to negate the entire condition
NOT: { name_EQ: "Keanu Reeves" },
# Only include people who acted in at least one movie with Keanu
movies_SOME: {
actors_SOME: { name_EQ: "Keanu Reeves" }
}
},
sort: [{ name: ASC }],
limit: 1000
) {
name
# Optionally include which movies they co-starred with Keanu in
movies(
where: { actors_SOME: { name_EQ: "Keanu Reeves" } },
sort: [{ title: ASC }]
) {
title
}
}
}
{
"data": {
"keanusMovies": [
{
"name": "Keanu Reeves",
"movies": [
{
"title": "Johnny Mnemonic",
"actors": [
{
"name": "Dina Meyer"
},
{
"name": "Ice-T"
},
{
"name": "Keanu Reeves"
},
{
"name": "Takeshi Kitano"
}
]
},
{
"title": "Something's Gotta Give",
"actors": [
{
"name": "Diane Keaton"
},
{
"name": "Jack Nicholson"
},
{
"name": "Keanu Reeves"
}
]
},
{
"title": "The Devil's Advocate",
"actors": [
{
"name": "Al Pacino"
},
{
"name": "Charlize Theron"
},
{
"name": "Keanu Reeves"
}
]
},
{
"title": "The Matrix",
"actors": [
{
"name": "Carrie-Anne Moss"
},
{
"name": "Emil Eifrem"
},
{
"name": "Hugo Weaving"
},
{
"name": "Keanu Reeves"
},
{
"name": "Laurence Fishburne"
}
]
},
{
"title": "The Matrix Reloaded",
"actors": [
{
"name": "Carrie-Anne Moss"
},
{
"name": "Hugo Weaving"
},
{
"name": "Keanu Reeves"
},
{
"name": "Laurence Fishburne"
}
]
},
{
"title": "The Matrix Revolutions",
"actors": [
{
"name": "Carrie-Anne Moss"
},
{
"name": "Hugo Weaving"
},
{
"name": "Keanu Reeves"
},
{
"name": "Laurence Fishburne"
}
]
},
{
"title": "The Replacements",
"actors": [
{
"name": "Brooke Langton"
},
{
"name": "Gene Hackman"
},
{
"name": "Keanu Reeves"
},
{
"name": "Orlando Jones"
}
]
}
]
}
],
"costars": [
{
"name": "Al Pacino",
"movies": [
{
"title": "The Devil's Advocate"
}
]
},
{
"name": "Al Pacino",
"movies": [
{
"title": "The Devil's Advocate"
}
]
},
{
"name": "Brooke Langton",
"movies": [
{
"title": "The Replacements"
}
]
},
{
"name": "Brooke Langton",
"movies": [
{
"title": "The Replacements"
}
]
},
{
"name": "Carrie-Anne Moss",
"movies": [
{
"title": "The Matrix"
},
{
"title": "The Matrix Reloaded"
},
{
"title": "The Matrix Revolutions"
}
]
},
{
"name": "Carrie-Anne Moss",
"movies": [
{
"title": "The Matrix"
},
{
"title": "The Matrix Reloaded"
},
{
"title": "The Matrix Revolutions"
}
]
},
{
"name": "Charlize Theron",
"movies": [
{
"title": "The Devil's Advocate"
}
]
},
{
"name": "Charlize Theron",
"movies": [
{
"title": "The Devil's Advocate"
}
]
},
{
"name": "Diane Keaton",
"movies": [
{
"title": "Something's Gotta Give"
}
]
},
{
"name": "Diane Keaton",
"movies": [
{
"title": "Something's Gotta Give"
}
]
},
{
"name": "Dina Meyer",
"movies": [
{
"title": "Johnny Mnemonic"
}
]
},
{
"name": "Dina Meyer",
"movies": [
{
"title": "Johnny Mnemonic"
}
]
},
{
"name": "Emil Eifrem",
"movies": [
{
"title": "The Matrix"
}
]
},
{
"name": "Emil Eifrem",
"movies": [
{
"title": "The Matrix"
}
]
},
{
"name": "Gene Hackman",
"movies": [
{
"title": "The Replacements"
}
]
},
{
"name": "Gene Hackman",
"movies": [
{
"title": "The Replacements"
}
]
},
{
"name": "Hugo Weaving",
"movies": [
{
"title": "The Matrix"
},
{
"title": "The Matrix Reloaded"
},
{
"title": "The Matrix Revolutions"
}
]
},
{
"name": "Hugo Weaving",
"movies": [
{
"title": "The Matrix"
},
{
"title": "The Matrix Reloaded"
},
{
"title": "The Matrix Revolutions"
}
]
},
{
"name": "Ice-T",
"movies": [
{
"title": "Johnny Mnemonic"
}
]
},
{
"name": "Ice-T",
"movies": [
{
"title": "Johnny Mnemonic"
}
]
},
{
"name": "Jack Nicholson",
"movies": [
{
"title": "Something's Gotta Give"
}
]
},
{
"name": "Jack Nicholson",
"movies": [
{
"title": "Something's Gotta Give"
}
]
},
{
"name": "Laurence Fishburne",
"movies": [
{
"title": "The Matrix"
},
{
"title": "The Matrix Reloaded"
},
{
"title": "The Matrix Revolutions"
}
]
},
{
"name": "Laurence Fishburne",
"movies": [
{
"title": "The Matrix"
},
{
"title": "The Matrix Reloaded"
},
{
"title": "The Matrix Revolutions"
}
]
},
{
"name": "Orlando Jones",
"movies": [
{
"title": "The Replacements"
}
]
},
{
"name": "Orlando Jones",
"movies": [
{
"title": "The Replacements"
}
]
},
{
"name": "Takeshi Kitano",
"movies": [
{
"title": "Johnny Mnemonic"
}
]
},
{
"name": "Takeshi Kitano",
"movies": [
{
"title": "Johnny Mnemonic"
}
]
}
]
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment