Writing Your First GraphQL Query
In this blog we will setup our iOS project for using Githubs GraphQL API
Understanding .graphql Files
Apollo iOS looks for files with the .graphql extension. These contain your GraphQL operation definitions — the queries, mutations, and fragments your app will use. Each operation becomes a Swift class/struct during code generation.
Query 1: Viewer Profile
Create a file called ViewerProfile.graphql inside the graphql/ folder:
query ViewerProfile {
viewer {
login
name
bio
avatarUrl
email
websiteUrl
company
location
createdAt
followers {
totalCount
}
following {
totalCount
}
repositories(first: 0) {
totalCount
}
starredRepositories(first: 0) {
totalCount
}
}
}
Line-by-line breakdown:
query ViewerProfile— The operation type (query) and name (ViewerProfile). Apollo generatesViewerProfileQueryfrom this.viewer— Root field that returns the authenticated user.login,name,bio, etc. — Scalar fields (strings, dates) we want.followers { totalCount }— We do not need the full list of followers, just the count. This is a great example of asking for only what you need.repositories(first: 0)— Thefirst: 0trick lets us get the count without fetching any actual repository objects.
Query 2: Search Repositories
Create SearchRepositories.graphql:
query SearchRepositories($query: String!, $first: Int!, $after: String) {
search(query: $query, type: REPOSITORY, first: $first, after: $after) {
repositoryCount
pageInfo {
hasNextPage
endCursor
}
edges {
node {
... on Repository {
id
name
nameWithOwner
description
stargazerCount
forkCount
url
primaryLanguage {
name
color
}
owner {
login
avatarUrl
}
viewerHasStarred
}
}
}
}
}
New concepts here:
$query: String!— A required variable of type String. The!means it cannot be null.$first: Int!— How many results to fetch per page.$after: String— An optional cursor for pagination (no!).search(query: $query, type: REPOSITORY, ...)— GitHub's search field accepts a search string and a type filter.... on Repository— This is a type condition (inline fragment). GitHub's search can return different types (Repository, User, Issue), so we use... on Repositoryto say "only give me these fields if the result is a Repository."
Query 3: Repository Detail
Create RepositoryDetail.graphql:
query RepositoryDetail($owner: String!, $name: String!) {
repository(owner: $owner, name: $name) {
id
name
nameWithOwner
description
url
homepageUrl
stargazerCount
forkCount
watchers {
totalCount
}
primaryLanguage {
name
color
}
owner {
login
avatarUrl
}
viewerHasStarred
issues(first: 10, states: OPEN, orderBy: { field: CREATED_AT, direction: DESC }) {
totalCount
nodes {
id
title
state
createdAt
author {
login
}
}
}
defaultBranchRef {
name
}
licenseInfo {
name
}
createdAt
updatedAt
}
}
This single query fetches everything a repository detail screen could need — general info, star/fork counts, the 10 most recent open issues, license info, and more. With REST, this would require 3–4 separate API calls.