measurement: align OpenAPI schemas with actual API responses and introduce DTO service contracts - #355
Conversation
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>
e08c24b to
04ad8af
Compare
| list=extend_schema( | ||
| summary='List measurements', | ||
| description=""" | ||
| Return a list of available measurements with their metadata. |
There was a problem hiding this comment.
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."
| retrieve=extend_schema( | ||
| summary='Get measurement', | ||
| description=""" | ||
| Return measurement details by measurement ID. |
There was a problem hiding this comment.
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."
| """, | ||
| responses={ | ||
| 200: OpenApiResponse( | ||
| response=MeasurementByResultSerializer, |
There was a problem hiding this comment.
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, |
There was a problem hiding this comment.
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.
| """, | ||
| responses={ | ||
| 200: OpenApiResponse( | ||
| response=MeasurementByResultSerializer, |
There was a problem hiding this comment.
response=MeasurementByResultSerializer is missing many=True — same issue as trend_charts, the view returns an array here too.
| }, | ||
| tags=[MEASUREMENT_TAG], | ||
| ), | ||
| trend_charts=extend_schema( |
There was a problem hiding this comment.
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).
| }, | ||
| tags=[MEASUREMENT_TAG], | ||
| ), | ||
| by_result_ids=extend_schema( |
There was a problem hiding this comment.
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=.
| responses={ | ||
| 200: OpenApiResponse( | ||
| response=MeasurementChartSerializer, | ||
| description='Measurement trend charts were succesfully retrieved', |
There was a problem hiding this comment.
Typo: "succesfully" → "successfully"
| responses={ | ||
| 200: OpenApiResponse( | ||
| response=MeasurementByResultSerializer, | ||
| description='Measurement data for result IDs were succesfully retrieved', |
There was a problem hiding this comment.
Typo: "succesfully" → "successfully"
| responses={ | ||
| 200: OpenApiResponse( | ||
| response=MeasurementByResultSerializer, | ||
| description='Measurement details were succesfully retrieved', |
There was a problem hiding this comment.
Typo: "succesfully" → "successfully"
04ad8af to
e1b8327
Compare
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>
e1b8327 to
9c79988
Compare
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
400response instead of an unhandled
500error.used by the current API implementation.
400and404error responses.behavior.