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

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages