Course outline

Spring Boot / Advanced: observability and resilient releases / Lesson 18

API evolution and release evidence

Evolve public representations and framework versions through explicit consumer contracts, security checks, migration compatibility, and honest release evidence.

About 5 min readContent reviewed
On this page

Lesson goals

  • Identify breaking changes beyond compilation.
  • Preserve a deliberate DTO serialization contract.
  • Assemble release evidence for real framework boundaries.

Consumers depend on more than method signatures

A public HTTP contract includes method/path, status, headers, field names, units, nullability, ordering, errors, authentication, authorization, and timing/retry expectations. A change can compile cleanly while breaking clients or weakening access. Adding a field is not automatically harmless for every strict consumer, and changing an amount's scale under the same name can silently corrupt interpretation.

Separate source/binary library compatibility from wire and behavioral compatibility. Maintain representative consumer fixtures and explicit version/deprecation rules. Do not serialize entity structure simply because an added field appears convenient. A stable API reflects a reviewed product contract, not whatever a new Jackson, persistence, or framework default happens to emit after an upgrade.

Make a serialized field name and unit explicit

The DTO fragment uses the Jackson annotation package appropriate to the selected Boot3.5 line and exposes priceCents as unitPriceCents. The explicit currency complements the integer minor-unit representation. This is a response model, not proof of domain validation or authorization. It requires the managed JSON dependencies and therefore remains non-runnable in isolation.

A field annotation does not decide allowed currencies, rounding, missingness, or whether the caller may see the product. Those contracts belong to domain and access layers. Keep internal property refactoring separate from deliberate wire changes, and inspect custom ObjectMapper settings and modules. Using a new major line's JSON package without reviewing the managed stack can produce incompatible source or runtime behavior.

java Illustrative Boot3.5 JSON response model
package training.catalog;

import com.fasterxml.jackson.annotation.JsonProperty;

record ProductResponse(long id, String name,
                       @JsonProperty("unitPriceCents") int priceCents,
                       String currency) {}

The wire name and intended minor-unit convention are explicit. No serialization, validation, or authorization was executed by this fragment.

Test the wire contract through a selected JSON slice

The illustrative @JsonTest checks the configured mapper's selected property name, value, and currency and ensures the internal priceCents name is absent. It needs the contextual DTO and Boot3.5 test dependencies and is not executed. This is a narrower question than a full request: security, routing, repository queries, and transaction behavior remain separate boundaries.

Test null/missing fields, enum evolution, dates and time-zone conventions, numeric limits, and approved error extensions where relevant. Avoid brittle whole-response snapshots when unordered error lists or unrelated metadata are not part of the guarantee. Conversely, do not ignore an exposed extra private field merely because the expected public fields still appear. Consumer safety requires an intentional field surface.

java Illustrative serializer-contract fixture
package training.catalog;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.json.JsonTest;
import static org.assertj.core.api.Assertions.assertThat;

@JsonTest
class ProductResponseJsonTest {
    @Autowired ObjectMapper mapper;
    @Test
    void preservesPriceRepresentation() {
        JsonNode json=mapper.valueToTree(new ProductResponse(42,"Notebook",1200,"USD"));
        assertThat(json.get("unitPriceCents").asInt()).isEqualTo(1200);
        assertThat(json.get("currency").asText()).isEqualTo("USD");
        assertThat(json.has("priceCents")).isFalse();
    }
}

The fixture states intended configured-mapper assertions. It does not represent an executed Spring slice or a live HTTP response.

Review dependency, configuration, and behavioral changes together

Pin the source baseline and compare release/migration notes for the chosen target. Managed dependencies, test packages, configuration properties, defaults, validation, serialization, security, and transaction behavior can all change. Do not mix4.x documentation snippets into3.5 code or claim compatibility solely because Java17 is accepted by both. A coherent resolved graph and actual consumer tests are necessary.

Stage migrations so supported old/new application versions can coexist or coordinate access explicitly. Preserve a rollback/forward-fix plan that accounts for committed data and external effects. Keep secrets outside test artifacts and avoid silent production schema generation. The release question is whether the intended service contract still holds, not only whether the new application starts.

Summarize evidence without extending its claims

Assemble domain tests, MVC/security denials, configuration binding, persistence and transaction integration, serialization contracts, bounded async/cache behavior, health meaning, packaging, and recovery checks at their actual authorized boundaries. Identify untested pieces and failure assumptions explicitly. A set of passing dependency-free models or parser checks cannot certify an unexecuted framework application or deployment.

Record version, scope, command, observed result, and retained artifact identity. This course's true runnable flags are reserved for complete local models actually validated; framework/config/test/deploy fragments remain false. No real service, project database, credential, or listener is needed to read it. A responsible release leaves the next engineer able to trace every important claim to concrete evidence and understand its limits.

Common errors and fixes

A DTO refactor changed a public field unexpectedly

Why it happens
Internal and wire contracts were coupled without tests.
How to fix it
Restore or deliberately version the representation and verify consumers.
Prevent it next time
Use scoped serialization/contract checks.

A major upgrade compiled but changed access behavior

Why it happens
Compilation did not cover effective security/configuration semantics.
How to fix it
Test intended identities, denials, and effective settings on the target stack.
Prevent it next time
Review migration notes and managed dependencies.

Release notes claimed tests that were not run

Why it happens
Intended fixtures were reported as observed evidence.
How to fix it
State exact scope and results, leaving unverified fragments explicit.
Prevent it next time
Keep parser/model/framework/deployment evidence separate.

Check your understanding

1. Changing priceCents to unitPriceCents compiled on the producer. What must be reviewed?

Show worked solution

Whether the wire field changed, its units/currency/nullability, consumer expectations, error compatibility, and security exposure. A producer build does not prove consumer safety. Use deliberate serialization and consumer contract tests rather than relying on Java source compatibility alone.

2. Which claims can this course's local model validation support?

Show worked solution

Only the demonstrated complete JDK calculations/policies and explicitly parsed fixture syntax. It cannot establish Spring binding, proxies, security filters, JPA transactions, actual HTTP, or deployment readiness without their own executed controlled tests. Keep every claim matched to its evidence.

Key takeaways

  • Compatibility includes behavior, representations, and operational assumptions.
  • Consumer and serializer contracts complement compilation.
  • Truthful evidence keeps unexecuted framework claims visible.

Official references