Skip to content

measurement: align OpenAPI schemas with actual API responses and introduce DTO service contracts - #355

Open
ol-zayatsm wants to merge 4 commits into
ts-factory:mainfrom
ol-zayatsm:measurements_swagger_update
Open

measurement: align OpenAPI schemas with actual API responses and introduce DTO service contracts#355
ol-zayatsm wants to merge 4 commits into
ts-factory:mainfrom
ol-zayatsm:measurements_swagger_update

Conversation

@ol-zayatsm

Copy link
Copy Markdown
Contributor

Description

Summary

Update API v2 measurement endpoints to use DTO-based service contracts,
fix invalid measurement ID handling, disable unused pagination, and align
OpenAPI schemas with the actual API responses.

Changes

  • Add DTOs for measurement chart and measurement-by-result responses.
  • Return DTOs from measurement service methods instead of dictionaries.
  • Serialize DTO-backed responses in measurement API endpoints.
  • Fix invalid measurement IDs so malformed values return a clear 400
    response instead of an unhandled 500 error.
  • Disable pagination for measurement endpoints where pagination is not
    used by the current API implementation.
  • Add and update OpenAPI schema definitions for measurement endpoints.
  • Document request payloads, success responses, and relevant 400 and
    404 error responses.
  • Keep OpenAPI definitions aligned with the current measurement API
    behavior.

Replace dict-based service responses with typed DTOs to introduce
explicit and structured data contracts across service boundaries
and move serialization to API boundary to improve separation of
concerns between service layer and API layers.

Signed-off-by: Mikhail Zayats <mikhail.zayats@oktetlabs.ru>
Remove pagination from MeasurementViewSet to align the generated list
documentation with the actual API behavior.

Signed-off-by: Mikhail Zayats <mikhail.zayats@oktetlabs.ru>
Values of the measurement ID that aren't valid integers
(e.g. /measurements/abc/ or /measurements/1.5/) raised an unhandled
ValueError when used in the database lookup, surfacing as an opaque
500 response instead of telling the client what was wrong.

Catch ValueError alongside ObjectDoesNotExist in get_measurement and
raise a ValidationError with a descriptive message, so an invalid
measurement ID returns a clear 400 error.

Signed-off-by: Mikhail Zayats <mikhail.zayats@oktetlabs.ru>
@ol-zayatsm
ol-zayatsm force-pushed the measurements_swagger_update branch from e08c24b to 04ad8af Compare August 15, 2026 17:14
list=extend_schema(
summary='List measurements',
description="""
Return a list of available measurements with their metadata.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Description is misleading — a measurement here is its set of metas, not an entity with metadata attached. Suggest: "Return a list of available measurements, each represented by its defining set of metadata."

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

retrieve=extend_schema(
summary='Get measurement',
description="""
Return measurement details by measurement ID.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same issue as list, a measurement isn't an entity with separate "details", it is its set of metas. Suggest: "Return the set of metadata that describes a measurement, identified by its ID."

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

""",
responses={
200: OpenApiResponse(
response=MeasurementByResultSerializer,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

retrieve schema declares response=MeasurementByResultSerializer, but the view still returns MeasurementSerializer's {"metas": [...]} shape (that serializer belongs to by_result_ids). Should be MeasurementListResponseSerializer — please fix.

""",
responses={
200: OpenApiResponse(
response=MeasurementChartSerializer,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

response=MeasurementChartSerializer is missing many=True — the view serializes with many=True and returns an array, so the schema will document a single object instead of a list.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

""",
responses={
200: OpenApiResponse(
response=MeasurementByResultSerializer,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

response=MeasurementByResultSerializer is missing many=True — same issue as trend_charts, the view returns an array here too.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

},
tags=[MEASUREMENT_TAG],
),
trend_charts=extend_schema(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No request= specified — drf-spectacular falls back to the viewset's default serializer_class (MeasurementSerializer, i.e. metas) as the request body schema, which doesn't match what the view actually reads (result_ids). Please add an explicit request=(e.g. inline_serializer with result_ids).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

},
tags=[MEASUREMENT_TAG],
),
by_result_ids=extend_schema(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as trend_charts — no request=, so the documented request body defaults to MeasurementSerializer instead of the actual result_ids payload. Please add an explicit request=.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

responses={
200: OpenApiResponse(
response=MeasurementChartSerializer,
description='Measurement trend charts were succesfully retrieved',

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo: "succesfully" → "successfully"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

responses={
200: OpenApiResponse(
response=MeasurementByResultSerializer,
description='Measurement data for result IDs were succesfully retrieved',

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo: "succesfully" → "successfully"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

responses={
200: OpenApiResponse(
response=MeasurementByResultSerializer,
description='Measurement details were succesfully retrieved',

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo: "succesfully" → "successfully"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

@ol-zayatsm
ol-zayatsm force-pushed the measurements_swagger_update branch from 04ad8af to e1b8327 Compare August 28, 2026 08:41
Ensure consistency between OpenAPI schemas and API responses by
introducing explicit request/response serializers and binding them via
drf-spectacular.

Signed-off-by: Mikhail Zayats <mikhail.zayats@oktetlabs.ru>
@ol-zayatsm
ol-zayatsm force-pushed the measurements_swagger_update branch from e1b8327 to 9c79988 Compare August 29, 2026 09:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants