DEV Community

HARRIFIED
HARRIFIED

Posted on • Edited on

Query Fragments with Conditions in GraphQL

Graphql + Apollo + React

OK let’s dive in real quick!

GraphQL is a query language and runtime that enables efficient data retrieval and manipulation from APIs. It allows clients to request specific data they need, reducing over-fetching and under-fetching issues commonly found in REST APIs. Its key benefits include increased flexibility, reduced network traffic, and improved developer productivity.

Now think of fragments as reusable units of fields used on the client side that can be defined and included in multiple queries. They allow you to define a set of fields once and use them in multiple places, making your queries more modular and concise.

Writing fragments is a good way to enhance code organization, reduce duplication, and make it easier to maintain and update queries as your schema evolves. They are particularly useful when you have common fields that are shared across different queries or when you want to abstract complex field selections into smaller, reusable components.

Let’s take a look at this example

#First we define a fragment for a user
fragment UserFragment on User {
  id
  name
  email
  age
}

# A query using the defined fragment
# We use ...UserFragment to include within the user query
query GetUser {
  user(id: 123) {
    ...UserFragment
  }
}

# Another query using the same fragment
# We use ...UserFragment to include within the users query
query GetUsers {
  users {
    ...UserFragment
  }
}
Enter fullscreen mode Exit fullscreen mode

OK with that being said let’s look at how we can query a fragment based on certain conditions from parent.

To query fragments based on certain conditions from a parent, you can use conditional directives or arguments in GraphQL. The specific implementation may vary depending on the GraphQL server or library you are using.

Let’s see how we can accomplish this using Apollo Client.

Let’s try to query a user’s profile and return all the fields. But we will conditionally include the user’s private posts or maybe liked posts based on the user Id, so we check if the post owner’s id is equal to the user Id. This can be a useful feature in a social media app.

OK let’s dive in!

credit: https://gifer.com/en/PDE

Here are the steps

First, we define the fragment for the user’s post, let’s call it UserLikedPostsFragment.

const userLikedPostsFragment = gql`
  fragment UserLikedPostsFragment on User {
    likedPosts {
      id
      content
    }
  }
`;
Enter fullscreen mode Exit fullscreen mode

The userLikedPostsFragment specifies the field for the user’s posts, it includes the id and the content fields for each post.

We then determine if the user is the owner of the post by comparing the user ID and the post owner’s ID. If they match, we set includeLikedPosts to true; otherwise, we set it to false

// Assuming we have the user's ID
const userId = 'bldo123';

// Assuming we have post owner id
const postOwnerId = '456jsksi';

// Check if the user ID matches the post's owner ID
const isPostOwner = (userId === postOwnerId);

// Determine if we should include the user's liked posts in the query
const includeLikedPosts = isPostOwner;
Enter fullscreen mode Exit fullscreen mode

Then, we create a GET_USER query that accepts the userId variable and an additional includeLikedPosts variable we just created. Inside the query, we conditionally include the UserLikedPostsFragment using the spread syntax (...) and the @include directive. The @include directive controls whether the fragment is included based on the value of includeLikedPosts

const GET_USER = gql`
  query GetUser($userId: ID!) {
    user(id: $userId) {
      id
      name
      email
      ...UserLikedPostsFragment @include(if: $includeLikedPosts)
    }
  }
`;
Enter fullscreen mode Exit fullscreen mode

learn more about directives in Apollo-Client here

Then we can go on to execute our query

client.query({
  query: GET_USER,
  variables: {
    userId,
    includeLikedPosts,
  },
}).then((result) => {
  // Handle query result anyhow you wish
  console.log(result.data.user);
});
Enter fullscreen mode Exit fullscreen mode

Notice the $includeLikedPosts variable is passed as a query variable when executing the query. Its value is determined based on the logic in the code (in this case, whether the user is the owner of the post).

By passing the variables (userId and includeLikedPosts) and the query to client.query, we can execute the query and handle the results accordingly.

So the LikedPosts will be returned if the condition is met that’s is if

userId === postOwnerId
Enter fullscreen mode Exit fullscreen mode

Here’s the code snippet demonstrating how you can conditionally include the user’s posts based on the user ID using fragments in Apollo Client:

import { ApolloClient, InMemoryCache, gql } from '@apollo/client';

const client = new ApolloClient({
 uri: 'https://your-graphql-api-endpoint',
 cache: new InMemoryCache(),
});


const userLikedPostsFragment = gql`
 fragment UserLikedPostsFragment on User {
 likedPosts {
   id
   content
 }
 }
`;

//Assuming we have the user's ID
const userId = 'bldo123';

// Assuming the user owns the post
const postOwnerId = '456jsksi';

//Check if the user ID matches the post's owner ID
const isPostOwner = (userId === postOwnerId);

// Determine if we should include the user's liked posts in the query
const includeLikedPosts = isPostOwner;
client.query({
 query: GET_USER,
 variables: {
 userId,
 includeLikedPosts,
 },
}).then((result) => {
 // Handle query result
 console.log(result.data.user);
});

Enter fullscreen mode Exit fullscreen mode

Hope you enjoyed the post. If you did hit the ❤️ button, share and follow for more amazing content. Bye 👋

Top comments (0)