ReadingBat Core
ReadingBat Core is a Kotlin-based web application framework for creating interactive programming challenges, powering the ReadingBat platform. It provides a powerful DSL for defining challenges in Java, Python, and Kotlin, a Ktor-based web server, and real-time feedback via WebSockets.
Key Features
- Content DSL -- Define programming challenges using an expressive Kotlin DSL
- Multi-language support -- Java, Python, and Kotlin challenges in a single application
- Local and remote content -- Load challenges from the local filesystem or GitHub repositories
- Real-time feedback -- WebSocket-powered answer checking and progress tracking
- Class management -- Teachers can create classes and monitor student progress
- Flexible configuration -- HOCON properties with environment variable overrides
Quick Start
Define your content using the readingBatContent builder:
val basicContent =
readingBatContent {
repo = FileSystemSource("./")
java {
group("Warmup-1") {
packageName = "warmup1"
description = "Simple warmup problems to get started"
includeFiles = "*.java"
}
}
}
This creates a content definition that:
- Loads Java source files from the local filesystem
- Organizes them into a group called "Warmup-1"
- Auto-discovers all
.javafiles in thewarmup1package
DSL Hierarchy
The content DSL follows a hierarchical structure:
graph TD
A[ReadingBatContent] --> B[LanguageGroup - Java]
A --> C[LanguageGroup - Python]
A --> D[LanguageGroup - Kotlin]
B --> E[ChallengeGroup]
B --> F[ChallengeGroup]
C --> G[ChallengeGroup]
E --> H[Challenge]
E --> I[Challenge]
F --> J[Challenge]
G --> K[Challenge]
ReadingBatContent LanguageGroup ChallengeGroup Challenge
Multi-Language Example
ReadingBat supports challenges in all three languages within a single content definition:
val multiLanguageContent =
readingBatContent {
repo = FileSystemSource("./")
java {
srcPath = "src/main/java"
group("Warmup-1") {
packageName = "warmup1"
description = "Simple Java warmup problems"
includeFiles = "*.java"
}
group("String-1") {
packageName = "string1"
description = "Basic string problems"
includeFiles = "*.java"
}
}
python {
srcPath = "python"
group("Warmup-1") {
packageName = "warmup1"
description = "Simple Python warmup problems"
includeFilesWithType = "*.py" returns BooleanType
}
}
kotlin {
srcPath = "src/main/kotlin"
group("Warmup-1") {
packageName = "warmup1"
description = "Simple Kotlin warmup problems"
includeFilesWithType = "*.kt" returns StringType
}
}
}
Java vs. Python/Kotlin
Java challenges use includeFiles because return types are inferred from source code.
Python and Kotlin challenges require includeFilesWithType with an explicit return type.
Architecture Overview
| Component | Description |
|---|---|
| Content DSL | Defines challenges via readingBatContent { } blocks |
| Ktor Server | Serves HTML pages and handles API requests |
| Script Engines | JSR-223 engines evaluate Java, Kotlin, and Python code |
| PostgreSQL | Stores user accounts, progress, and class data |
| WebSockets | Provides real-time answer checking and dashboard updates |
| Prometheus | Exports metrics for monitoring |
API Reference
Full API documentation (KDocs) is available at KDocs.
Next Steps
-
Content DSL
Learn how to define challenges using the Kotlin DSL
-
Configuration
Configure the application with HOCON and environment variables
-
Server
Understand the Ktor server setup and routing
-
Testing
Write tests using the Kotest test support utilities