SDK: Simplify OpenAPI Spec annotations
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 30/100
Research direction
Start with the metrics records named in the issue, such as ProjectJobScheduleInputMetrics, and the @Schema annotations on their components. The proposal has two open implementation options (a Jandex AnnotationTransformation in timefold-solver-service-quarkus-deployment, or an OASFilter at runtime), so a maintainer has to choose one before any code is written. Done means a @Metric annotation that expands to the same OpenAPI output the quickstarts produce by hand today.
Written by the indexing model from the issue text.
Description
Is your feature request related to a problem? Please describe.
It's very frustrating to see how complex our OpenAPI Spec annotations have become to be platform compatible.
Every metric component on a ModelInputMetrics / ModelOutputMetrics record carries a large @Schema
annotation. Most of it repeats the same values on every field, and the example value is written twice.
This is one field from ProjectJobScheduleInputMetrics, which already has the inferred attributes
(type, name, @JsonFormat) removed:
@Schema(title = "Jobs", format = DataFormat.Values.NUMBER,
description = "The number of jobs submitted in the input dataset.",
examples = "24", minimum = "0", readOnly = true,
extensions = { @Extension(name = X_TF_PRIORITY, value = "2"),
@Extension(name = X_TF_EXAMPLE, value = "24") }) int jobs,
Only the following are specific to each metric:
titledescription- the example value
format, when it isn'tNUMBER
Everything else is either the same on every metric or can be derived:
| Attribute | Why it's boilerplate |
|---|---|
readOnly = true |
Always true: metrics are only serialized, never deserialized. |
minimum = "0" |
True for every count/total metric in the quickstarts so far. |
x-tf-example |
Duplicates examples. |
x-tf-priority |
Order in the Platform UI, this should honestly just have a default and be hidden |
X_TF_PRIORITY / X_TF_EXAMPLE constants |
Redeclared as private constants in every metrics class. |
Across the migrated quickstarts, this makes the metrics records hard to read, and it's easy to slip
(for example, an examples that no longer matches its x-tf-example).
Describe the solution you'd like
Add an SDK annotation, for example ai.timefold.solver.service.definition.api.metrics.Metric, that
carries only the metric-specific information:
public record ProjectJobScheduleInputMetrics(
@Metric(title = "Allocations", example = "24",
description = "The number of job allocations submitted in the input dataset.") int allocations,
@Metric(title = "Jobs", example = "24",
description = "The number of jobs submitted in the input dataset.") int jobs,
@Metric(title = "Projects", example = "2",
description = "The number of projects submitted in the input dataset.") int projects,
@Metric(title = "Resources", example = "7",
description = "The number of resources submitted in the input dataset.") int resources)
implements
ModelInputMetrics {
...
}
Sketch of the annotation:
@Target({ ElementType.FIELD, ElementType.RECORD_COMPONENT, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface Metric {
String title();
String description();
String example();
String format() default DataFormat.Values.NUMBER;
String minimum() default "0"; // "" to omit
int priority() default -1; // -1 = derive from declaration order
}
The SDK expands @Metric into the same OpenAPI output that the quickstarts produce by hand today:
title,descriptionandformatcome straight from the annotation.exampleandx-tf-exampleboth come fromexample.readOnly: trueis always set.minimumdefaults to0.x-tf-prioritycomes from the component index (1-based) unlesspriorityis set explicitly.typeis inferred from the Java type, as it is today.
Implementation options
- Build time, via a Jandex
AnnotationTransformationintimefold-solver-service-quarkus-deployment.
It rewrites@Metricinto an equivalent@Schema(with@Extensions) on classes implementing
ModelInputMetrics/ModelOutputMetrics. SmallRye OpenAPI then sees a normal@Schema, so nothing
downstream changes. This option is preferred because the static spec is correct at build time too. - Runtime, via an
OASFilterthat finds the metrics schemas and fills in the properties.
It's simpler to write, but it relies on reflection to map schema properties back to record components.
Describe alternatives you've considered
Leaving it as is... for the user to deal with.
- Dominant language
- Java
- Stars
- 1.8k
- Forks
- 238
- Avg merge
- 3d 1h
- Merged PRs (30d)
- 55
Getting set up
- No Dockerfile or Docker Compose file
- No pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from TimefoldAI/timefold-solver
-
component/docs
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
TimefoldAI/timefold-solver#2671 ·
Maintainers usually reply within 1 day
-
process/needs triage
Difficulty 5/5 Over a week Newbie friendliness 12/100
TimefoldAI/timefold-solver#2763 · 1 comment ·
Maintainers usually reply within 1 day
-
Docs: Add keywords for search.Possibly taken @TomCools claimed this today. Opencomponent/docs
TimefoldAI/timefold-solver#2762 · 1 assignee ·
Maintainers usually reply within 1 day
-
Swap move selector applies entity value range filtering to entity classes without entity-level rangesPossibly taken @zepfred claimed this 1 day ago. Openprocess/needs triage
TimefoldAI/timefold-solver#2761 · 1 assignee ·
Maintainers usually reply within 1 day
-
SDK: Waypoints class has not OpenAPI Spec annotations.Possibly taken @TomCools claimed this 1 day ago. Opencomponent/service
TimefoldAI/timefold-solver#2759 · 1 assignee ·
Maintainers usually reply within 1 day
All issues in TimefoldAI/timefold-solver
Similar issues
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
OpenIntegrationEngine/engine#496 ·
Maintainers usually reply within 1 day
-
enhancement good first issue
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
SasanLabs/VulnerableApp#836 ·
Maintainers usually reply within 1 day
-
enhancement frontend
Difficulty 2/5 1-3 hours Newbie friendliness 83/100
Albertinesilva/backend-engineering-journey-java-springboot#46 ·
-
Snyk: vulnerabilities in jackson-databind 2.21.5Possibly taken @harrywu23 claimed this today. Openbug
Difficulty 1/5 1-3 hours Newbie friendliness 80/100
SOFTENG-310-Group-4/Project-A1-310-Group-4#115 ·
Maintainers usually reply within 1 day
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
carlos-emr/carlos#4833 · 1 comment ·
Maintainers usually reply within 1 day