Star Wars Tutorial

As example, let's partially reproduce part of Star Wars schema from official GraphQL tutorial. First, we need to define our domain model, by plain kotlin classes:

enum class Episode {
  NEWHOPE, EMPIRE, JEDI
}

interface Character {
  val id : String
  val name : String?
  val friends: List<Character>
  val appearsIn: Set<Episode>
}

data class Human (
  override val id: String,
  override val name: String?,
  override val friends: List<Character>,
  override val appearsIn: Set<Episode>,
  val homePlanet: String,
  val height: Double
) : Character

data class Droid (
  override val id: String,
  override val name: String?,
  override val friends: List<Character>,
  override val appearsIn: Set<Episode>,
  val primaryFunction : String
) : Character

Next, we define our data

val luke = Human("2000", "Luke Skywalker", emptyList(), Episode.values().toSet(), "Tatooine", 1.72)

val r2d2 = Droid("2001", "R2-D2", emptyList(), Episode.values().toSet(), "Astromech")

Then, we can create schema:

// KGraphQL#schema { } is entry point to create KGraphQL schema
val schema = KGraphQL.schema {
  //configure method allows you customize schema behaviour
  configure {
    useDefaultPrettyPrinter = true
  }

  // create query "hero" which returns instance of Character
  query("hero") {
    resolver { episode: Episode ->
      when (episode) {
        Episode.NEWHOPE, Episode.JEDI -> r2d2
        Episode.EMPIRE -> luke
      }
    }
  }

  // create query "heroes" which returns list of luke and r2d2
  query("heroes") {
    resolver{ -> listOf(luke, r2d2) }
  }

  // 1kotlin classes need to be registered with "type" method 
  // to be included in created schema type system
  // class Character is automatically included, 
  // as it is return type of both created queries  
  type<Droid>()
  type<Human>()
  enum<Episode>()
}

Now, we can query our schema:

// query for hero from episode JEDI and take id, name for any Character, and primaryFunction for Droid or height for Human
schema.execute("""
  {
    hero(episode: JEDI) {
      id
      name
      ... on Droid {
        primaryFunction
      }
      ... on Human {
        height
      }
    }
  }
""")

Returns:

{
  "data" : {
    "hero" : {
      "id" : "2001",
      "name" : "R2-D2",
      "primaryFunction" : "Astromech"
    }
  }
}

Query for all heroes:

// query for all heroes and take id, name for any Character, and primaryFunction for Droid or height for Human
schema.execute("""
  {
    heroes {
      id
      name
      ... on Droid {
        primaryFunction
      }
      ... on Human {
        height
      }
    }
  }
""")

Returns:

{
  "data" : {
    "heroes" : [
      {
        "id" : "2000",
        "name" : "Luke Skywalker",
        "height" : 1.72
      },
      {
        "id" : "2001",
        "name" : "R2-D2",
        "primaryFunction" : "Astromech"
      }
    ]
  }
}

As stated by GraphQL specification, client receives only what is requested. No more, no less.