Demo data (optional)
Providing example datasets is a good way to help consumers understand the expected input of your model. This page describes how to provide dedicated support for exposing demo data.
|
This page describes features which are only relevant when running Timefold Solver as a service. The information on these pages may describe functionality which may be changed or even removed in a future release. |
1. Generating demo data
To provide consumers of your model with example datasets, implement the DemoDataGenerator interface.
This interface requires you to implement 2 methods:
-
demoMetaData(): returns a list of metadata, listing all the different datasets available. -
generateDemoData(String demoDataId): generates the dataset with the given id, usually retrieved from the metadata.
|
Implementations of this interface must be dependency free meaning simple instantiation (even with reflection) of this class is enough to generate demo data. |
-
Java
-
Kotlin
@ApplicationScoped
public class TimetableDemoDataGenerator implements DemoDataGenerator {
public enum DemoDataKind {
BASIC(
new DemoMetaData("BASIC", "SHORT_DESCRIPTION", "LONG_DESCRIPTION", List.of("TAGS"),
List.of()),
DemoDataKind::generateBasicDemoData // could also delegate to another class instead
),
COMPLEX_SET(
new DemoMetaData("COMPLEX_SET", "SHORT_DESCRIPTION", "LONG_DESCRIPTION", List.of("TAGS"),
List.of()),
DemoDataKind::generateComplexSet
);
private final DemoMetaData metaData;
private final Function<DemoDataKind, ModelRequest<TimetableInput, TimetableConfigOverrides>> requestFunction;
DemoDataKind(DemoMetaData metaData,
Function<DemoDataKind, ModelRequest<TimetableInput, TimetableConfigOverrides>> requestFunction) {
this.metaData = metaData;
this.requestFunction = requestFunction;
}
public DemoMetaData getMetaData() {
return metaData;
}
public DemoData getDemoData() {
return new DemoData(metaData, requestFunction.apply(this));
}
public ModelRequest<TimetableInput, TimetableConfigOverrides> generateBasicDemoData() {
// Generate basic request.
}
public ModelRequest<TimetableInput, TimetableConfigOverrides> generateComplexSet() {
// Generate complex request.
}
}
@Override
public List<DemoMetaData> demoMetaData() {
return Stream.of(DemoDataKind.values())
.map(demoDataKind -> demoDataKind.getMetaData())
.toList();
}
@Override
public DemoData generateDemoData(String demoDataId) {
return DemoDataKind.fromString(demoDataId).getDemoData();
}
}
@ApplicationScoped
class TimetableDemoDataGenerator : DemoDataGenerator {
enum class DemoDataKind(
private val metaData: DemoMetaData,
private val requestFunction: (DemoDataKind) -> ModelRequest<TimetableInput, TimetableConfigOverrides>
) {
BASIC(
DemoMetaData("BASIC", "SHORT_DESCRIPTION", "LONG_DESCRIPTION", listOf("TAGS"), listOf()),
{ it.generateBasicDemoData() } // could also delegate to another class instead
),
COMPLEX_SET(
DemoMetaData("COMPLEX_SET", "SHORT_DESCRIPTION", "LONG_DESCRIPTION", listOf("TAGS"), listOf()),
{ it.generateComplexSet() }
);
fun getMetaData(): DemoMetaData = metaData
fun getDemoData(): DemoData = DemoData(metaData, requestFunction(this))
fun generateBasicDemoData(): ModelRequest<TimetableInput, TimetableConfigOverrides> {
return TODO("Generate basic request.")
}
fun generateComplexSet(): ModelRequest<TimetableInput, TimetableConfigOverrides> {
return TODO("Generate complex request.")
}
}
override fun demoMetaData(): List<DemoMetaData> {
return DemoDataKind.entries.map { it.getMetaData() }
}
override fun generateDemoData(demoDataId: String): DemoData {
return DemoDataKind.fromString(demoDataId).getDemoData()
}
}
With this interface implemented, Timefold Solver will automatically expose these methods as REST endpoints:
-
GET /<root>/demo-data: Retrieve all available demo dataset ids. -
GET /<root>/demo-data/{demoDataId}: Retrieve the demo dataset with the given identifier