Could I use few queries in another query in GraphQL? - graphql

For example, I have two queries:
query FirstOne {
city {
id
name
}
}
and
query SecondOne {
person {
id
name
}
}
Can I do something like this?
query CombinedQuery {
FirstOne
SecondOne
}
I want to reduce query duplications because if I can't create a query like CombinedQuery I will need to create it in this way:
query CombinedQuery {
city {
id
name
}
person {
id
name
}
}
From my perspective - this query is bad.

Related

How to add filter to nested objects in GraphQL the GraphQL way?

Say I want to query an object tree like this:
query UsersWithOrgs {
users {
nodes {
firstName
lastName
orgMemberships {
nodes {
joinedAt
organization {
name
foundedAt
location {
city
country
}
}
}
}
}
}
}
Now say I want to filter for only the users where the org they joinedAt <= 6 months ago, or only the users where the org they joined is in England.
query UsersWhereJoinedRecently {
users {
nodes {
firstName
lastName
orgMemberships(joinedAt: { lte: "2022/03/12" }) {
nodes {
joinedAt
organization {
name
foundedAt
location {
city
country
}
}
}
}
}
}
}
query UsersWhereOrgInEngland {
users {
nodes {
firstName
lastName
orgMemberships {
nodes {
joinedAt
organization {
name
foundedAt
location(country: "England") {
city
country
}
}
}
}
}
}
}
Is this the "GraphQL way" of defining filters on nested objects? Or should the filters be hoisted up somehow?
Based on the definitions above, I would instead expect UsersWhereJoinedRecently to return all users in the app, but orgMemberships would be filtered to only include those after the joinedAt date. Likewise, I would expect UsersWhereOrgInEngland to return all users with all their orgs, but only return the location for the org if the country is "England". That is not at all what I want, I want only the users where if that deeply nested condition is false, not to return the user. What is the appropriate way people handle this situation?
To me there are two passes in the overall query:
Joins and Wheres.
Projection.
First, we must fetch all users where the deeply nested condition is true. Then given those top-level IDs for the user, we fetch the projected schema.
So first:
// userIds =
select id from users
inner join memberships on memberships.userId = users.id
where memberships.joinedAt <= "2022/03/12"
Then:
select firstName, lastName from users where id in userIds
select joinedAt, orgId from orgMemberships where userId in userIds and joinedAt <= "2022/03/12"
... select from each of the other tables.
... then build into tree and return to client.
Same with the other query.
So because of these two seemingly completely separate phases, it makes me think that all filtering should be passed in at the top level in some fashion in GraphQL. Like:
query UsersWhereJoinedRecently {
users(membershipJoinedAt: { lte: "2022/03/12" }) {
nodes {
firstName
lastName
orgMemberships {
nodes {
joinedAt
organization {
name
foundedAt
location {
city
country
}
}
}
}
}
}
}
Is that correct, is that the recommended practice? Or what is recommended practice in these sorts of "filter by nested objects" scenarios?

GraphQL using a dynamic ID from set of returned results to render correct set of data

I am pretty new to graphql, so my question might sound a bit strange. it may not be correct way of doing what I need, but I can't think of any other way.
Basically, I would like to know how I can use an ID i am being returned from my graphql query and use that ID in the second query to render the data I need.
currently my full query looks like:
export const query = graphql`
query myQuery {
allSanityFrontpage {
nodes {
content {
... on SanityHero {
_key
_type
heroIntro
heroHeader
heroButtonText
heroProjectReference {
id
title
slug {
current
}
}
}
}
}
}
sanityProject(id: { eq: "-8571b76b-8cfd-55cf-b848-151586f5c57a" }) {
id
title
coverImage {
asset {
title
fluid(maxWidth: 800) {
...GatsbySanityImageFluid
}
}
}
}
}
`;
I am getting an ID returned from this part of the query
heroProjectReference {
id
And currently I am using that ID statically to render the content I need by doing this:
sanityProject(id: { eq: "-8571b76b-8cfd-55cf-b848-151586f5c57a" }) {
id
title
How do I replace that static ID with something dynamic, so I can update my CMS and see whatever project I have updated it to be?
Client-side you must call the chained queries serially, populating the ID in the dependent query with the output from the first query.
Server-side, of course, you can combine the two in the resolver.

Graphql Filter by query

So I'm trying to learn graphql I've been playing around with the ENS subgraph on the graph
I've figured out how to do simple filtering but when I try to write more complex filters they do not compile.
I'm trying to get the top 5 transactions for the each of the top 5 domains. (e.g for each domain I want the top 5 transactions)
{
#Sample Query to get the first 5 domains (not needed for question but used to validate results)
domains(first: 5) {
id
name
labelName
labelhash
}
#attempt to filter the transfer.domain.id by TOP 5 domains.id
transfers(where: { domain { id: domains(first: 5) { id } } }) {
id
domain {
id
}
blockNumber
transactionID
}
}
EDIT I'm going to attempt to simplify my request since I'm not sure nesting queries is possible. How can I filter an inner query by Id:
transfers(where: {domain.id: "0x9c0fc2519ae862cee27778e5c34714d6c7e3ca21ad572df47ad9f6fe530909bd"}) {
id
domain {
id
}
blockNumber
transactionID
}
NOTE: Domain.Id = does not compile how would I write a filtered query like that?
However, My filter doesn't compile syntactically. How can I write a query which filters by a child property?
You can query like this
query {
getPost(id: "0x1") {
title
text
datePublished
}
}
Got this from https://dgraph.io/docs/graphql/queries/search-filtering/

Dynamically pass required fields into GraphQL query

I have a query where my required fields inside the query may change. User is allowed to generate the query on fly and user can select the fields in the query. Is there a way to pass the required fields into query based on user's selection from a dropdown. Eg: in below query id, traveller, visaApplication can be replaced by anyother fields. So my queries has to dynamic.
{
Travels{
id
traveller {
nationality
firstName
}
visaApplication {
nationality
city
}
}
}
Fields can be added dynamically using string interpolation:
const otherFields = `
traveller {
nationality
firstName
}
`
const query = gql`
{
Travels {
id
${otherFields}
}
}
`
You can also utilize the #skip or #include directives, combined with variables, to control whether to skip/include particular fields for a specific request while utilizing a single query:
const query = gql`
query (
$includeTraveller: Boolean!
$includeVisa: Boolean!
) {
Travels {
id
traveller #include(if: $includeTraveller) {
nationality
firstName
}
visaApplication #include(if: $includeVisa) {
nationality
city
}
}
}
`

GraphQL-java add variables to query

I am new to GraphQL. I know this is a basic question but hope someone could help me to add variables to my query as I tried many times and failed :(
In my query, below schema is used:
type Query {
ContinentInfo(id: ID): Continent
}
type Continent {
id : ID
name: String
countries: [Country]
}
type Country {
id : ID
name : String
population: Float
}
Below query is executed successfully:
{
ContinentInfo(id: "continent01") {
name
countries {
name
population
}
}
}
Then I want to add more conditions in the query, for example add a variable "populationMoreThan" to filter the result. so the query may look like:
{
ContinentInfo(id: "continent01") {
name
countries(populationMoreThan: $populationMoreThan) {
name
population
}
}
}
but it always failed when I tried to add this variable in the schema and in the query.
Could anyone provide me an example of adding variable in my case?
Also, it looks I need to pass the parameter value into the query? Now I'm using graphql.GraphQL.execute(queryString) to pass the query string. How to pass the variable value here?
Finally found a way to filter the result.
Update the schema with:
type Continent {
id : ID
name: String
countries(populationMoreThan: Float = 0): [Country]
}
And query with:
{
ContinentInfo(id: "continent01") {
name
countries(populationMoreThan: 1.0) {
name
population
}
}
}

Resources