Queries
A query reads data; mutations write. Queries are POST /graphql requests with a query string + optional variables. Servers return only the fields you asked for — no over- or under-fetching.
Query syntax + client patterns
EXAMPLE
# 1) Basic shape
query {
me {
id
name
email
}
}
# 2) Arguments
query {
user(id: "u_42") {
name
email
}
}
# 3) Variables — never inline user input
query GetUser($id: ID!) {
user(id: $id) {
name
email
}
}
# variables: { "id": "u_42" }
# 4) Multiple roots in one request
query Dashboard($userId: ID!) {
me { name }
user(id: $userId) { posts(first: 5) { title } }
feed(first: 10) { id title }
}
# 5) Aliases — same field twice with different args
query {
current: user(id: "me") { name }
other: user(id: "u_42") { name }
}
# 6) Fragments — reusable selection sets
fragment UserCard on User {
id
name
avatarUrl
}
query {
me { ...UserCard }
friends { ...UserCard }
}
# 7) Directives — @include / @skip
query UserProfile($id: ID!, $withPosts: Boolean!) {
user(id: $id) {
name
posts @include(if: $withPosts) { title }
}
}
# 8) Pagination — cursor-based (Relay style)
query Feed($after: String) {
feed(first: 20, after: $after) {
edges {
cursor
node { id title }
}
pageInfo { hasNextPage endCursor }
}
}
# --- Client side (JS, fetch) ---
const body = JSON.stringify({
query: `query($id: ID!) { user(id: $id) { name email } }`,
variables: { id: 'u_42' },
operationName: 'GetUser',
});
const r = await fetch('/graphql', {
method: 'POST',
headers: { 'content-type': 'application/json' },
body,
});
const { data, errors } = await r.json();
if (errors) throw errors;
# --- urql / Apollo / TanStack Query handle this for you ---
import { useQuery, gql } from '@apollo/client';
const GET_USER = gql`
query GetUser($id: ID!) {
user(id: $id) {
name
email
}
}
`;
function Profile({ id }) {
const { loading, error, data } = useQuery(GET_USER, { variables: { id } });
if (loading) return <Spinner />;
if (error) return <ErrorBox error={error} />;
return <h1>{data.user.name}</h1>;
}
Why it matters
Use named operations + variables, never string-concatenated queries. Servers log operation names, dashboards group by them, and you get caching keyed off the name + variables for free.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Exercise
Top-level read entry point is…
type
{ user(id: ID!): User }
Five letters; PascalCase.
Discussion
Loading…