Skip to content

viaduct-dev/starwars

Repository files navigation

Star Wars Demo App

Doc type: Reference

This is a sample GraphQL application built using Viaduct, a composable GraphQL server in Kotlin.

This app models the Star Wars universe with characters, films, species, planets, and starships. It demonstrates how to implement resolvers, field-level context, pagination, fragments, and mock data using Viaduct’s conventions.

Requirements

  • Java JDK 21
  • JAVA_HOME is correctly set, or java is available in your PATH

Quick start

Start the demo app

./gradlew run

This will start the server at http://localhost:8080.

Access GraphiQL

Open your browser and go to GraphiQL interface:

http://localhost:8080/graphiql

Try example queries

Basic characters query

query {
  allCharacters(limit: 5) {
    id
    name
    homeworld {
      name
    }
  }
}

Scoped queries

The ViaductGraphQLController.kt applies scope metadata from the X-Viaduct-Scopes header into the GraphQL context.

Some fields—like Species.culturalNotes are marked with @scope(to: ["extras"]). These will only resolve if the "extras" scope is present in the context.

Use a query like:

query {
  node(id: "U3BlY2llczox") {
    ... on Species {
      name
      culturalNotes
      specialAbilities
    }
  }
}

In GraphiQL, add this to the Headers tab below the query pane:

{
  "X-Viaduct-Scopes": "extras"
}

Complex query with batch resolution

Run a complex character query with batch‑resolved fields.

query {
  allCharacters(limit: 3) {
    name
    homeworld { name }
    species { name }
    filmCount
    richSummary
  }
}

Fields such as filmCount and richSummary are computed by Character resolvers. @See CharacterResolvers.kt, SpeciesBatchResolver.kt and FilmCountBatchResolver.kt.

Resolution is batched by Viaduct’s resolver execution model (and/or DataLoaders if configured), which helps avoid N+1 patterns when the query asks these derived fields across multiple characters.

Film query with characters

Query films with their main characters

query {
  allFilms {
    title
    director
    mainCharacters {
      name
      homeworld { name }
    }
  }
}

Nodes and global IDs

A central concept in Viaduct is the Node: any object retrievable by a globally unique ID. Every Node has an id field.

Internally, a Viaduct ID consists of as base64-encoded string :

TypeName:LocalId

For example:

Character:5 → "Q2hhcmFjdGVyOjU="

In GraphiQL you can use the key icon in the toolbar (🔑) to encode or decode these IDs.

Example: look up a character by ID

query {
  node(id: "Q2hhcmFjdGVyOjU=") {
    ... on Character {
      name
      homeworld {
        id
      }
    }
  }
}

Returns:

{
  "data": {
    "node": {
      "name": "Obi-Wan Kenobi",
      "homeworld": {
        "id": "UGxhbmV0OjQ="
      }
    }
  }
}

You request the identifier UGxhbmV0OjQ= as a node query to retrieve the name of this planet:

query {
  node(id: "UGxhbmV0OjQ=") {
    ... on Planet {
      name
    }
  }
}

If you decode the id from base64, you can notice that the id UGxhbmV0OjQ= is decoded to "Planet:4".

Which returns:

{
  "data": {
    "node": {
      "name": "Stewjon"
    }
  }
}

Technical deep dive

For a deeper technical explanation of how the system works, see the Getting Started Guide.

About

Star Wars demo app showcasing Viaduct GraphQL features including resolvers, pagination, and fragments

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages