Skip to content

fix(rest): omit empty spec and status#16082

Draft
bartsmykla wants to merge 5 commits intomasterfrom
fix/omit-empty-spec-status
Draft

fix(rest): omit empty spec and status#16082
bartsmykla wants to merge 5 commits intomasterfrom
fix/omit-empty-spec-status

Conversation

@bartsmykla
Copy link
Copy Markdown
Contributor

Motivation

The REST API returns spec: {} and status: {} for resources with empty spec or status. Found during MeshOpenTelemetryBackend testing - MOTB with no spec returned spec: {}, and MeshMetric on global CP showed status: {}.

Implementation information

v1alpha1.Resource.MarshalJSON() calls core_model.ToJSON() on non-nil spec/status (every resource's GetSpec() returns &EmptyStruct{}, never nil). Empty structs marshal to {}, and json.RawMessage("{}") has length 2 - omitempty only omits nil/zero-length slices, so the field is always included.

After marshaling spec/status to JSON bytes, check if the result is "{}" and skip assignment. This leaves json.RawMessage as nil so omitempty omits the field. Same pattern already used by unversioned.Resource.MarshalJSON().

Round-trip safety verified: every generated SetSpec(nil) initializes to &EmptyStruct{}, so missing spec and spec: {} converge to the same state after deserialization.

Supporting documentation

Found during MeshOpenTelemetryBackend manual testing.

The v1alpha1 REST serializer always included spec and status
fields even when they serialized to empty JSON objects.
GetSpec()/GetStatus() return non-nil pointers to empty
structs, which marshal to "{}". json.RawMessage("{}") has
length 2 so omitempty doesn't omit it.

Skip assigning the marshaled bytes when the result is "{}",
matching the pattern used by unversioned.Resource.

Signed-off-by: Bart Smykla <bartek@smykla.com>
@bartsmykla bartsmykla added the ci/run-full-matrix PR: Runs all possible e2e test combination (expensive use carefully) label Apr 1, 2026
Copilot AI review requested due to automatic review settings April 1, 2026 08:15
@bartsmykla bartsmykla requested a review from a team as a code owner April 1, 2026 08:15
@bartsmykla bartsmykla requested review from lobkovilya and lukidzi April 1, 2026 08:15
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the REST v1alpha1 resource JSON marshaling to omit spec and/or status when they serialize to an empty JSON object ({}), aligning output with omitempty expectations and existing behavior in the unversioned.Resource marshaler.

Changes:

  • Update pkg/core/resources/model/rest/v1alpha1.Resource.MarshalJSON() to skip assigning spec/status when marshaled bytes equal "{}".
  • Add unit tests covering omission of non-nil empty spec and status.
  • Refresh API-server golden JSON fixtures to reflect the new omission behavior.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.

File Description
pkg/core/resources/model/rest/v1alpha1/resource.go Skip emitting spec/status when marshaled value is {} so omitempty can omit fields.
pkg/core/resources/model/rest/v1alpha1/resource_test.go Add coverage for non-nil empty spec and status being omitted.
pkg/api-server/testdata/resources/crud/*.golden.json Update expected REST responses to no longer include empty spec/status.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 1, 2026

Reviewer Checklist

🔍 Each of these sections need to be checked by the reviewer of the PR 🔍:
If something doesn't apply please check the box and add a justification if the reason is non obvious.

  • Is the PR title satisfactory? Is this part of a larger feature and should be grouped using > Changelog?
  • PR description is clear and complete. It Links to relevant issue as well as docs and UI issues
  • This will not break child repos: it doesn't hardcode values (.e.g "kumahq" as an image registry)
  • IPv6 is taken into account (.e.g: no string concatenation of host port)
  • Tests (Unit test, E2E tests, manual test on universal and k8s)
    • Don't forget ci/ labels to run additional/fewer tests
  • Does this contain a change that needs to be notified to users? In this case, UPGRADE.md should be updated.
  • Does it need to be backported according to the backporting policy? (this GH action will add "backport" label based on these file globs, if you want to prevent it from adding the "backport" label use no-backport-autolabel label)

Signed-off-by: Bart Smykla <bartek@smykla.com>
Signed-off-by: Bart Smykla <bartek@smykla.com>
@bartsmykla bartsmykla marked this pull request as draft April 1, 2026 09:30
@bartsmykla bartsmykla marked this pull request as draft April 1, 2026 09:30
Signed-off-by: Bart Smykla <bartek@smykla.com>
Add optional_spec marker and descriptor field so only
MOTB omits empty spec. Other resources keep spec: {}
as required by their OpenAPI schemas. Status omission
stays global for all resources.

Signed-off-by: Bart Smykla <bartek@smykla.com>
@lahabana
Copy link
Copy Markdown
Contributor

lahabana commented Apr 2, 2026

Is there a strong reason to do this?
@johncowen I think you prefer empty objects to missing ones no?

@johncowen
Copy link
Copy Markdown
Contributor

At my brief read of the description, yes it sounds like I would prefer a good default, and in this case always have a spec (is there a reason why a policy would never have a spec?)

I guess I have the same question as @lahabana:

Is there a strong reason to do this?


Generally good defaults is fairly easy with simple values like strings, booleans etc. Harder with objects, I'd usually prefer empty objects rather than non-existent field, unless there is good reason of course.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci/run-full-matrix PR: Runs all possible e2e test combination (expensive use carefully)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants