Writing Your First GraphQL Query

April 25, 2026

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 generates ViewerProfileQuery from 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) — The first: 0 trick 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 Repository to 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.