Skip to content

Conversation

@ichung08
Copy link
Collaborator

@ichung08 ichung08 commented Jan 28, 2026

Description

Add automatic field capture for RemoveField and AddField version change operations. When a field is removed from a request during version migration, its value is now automatically captured in the Gin context. When AddField is used in the response migration for the same field name, the captured value is restored instead of using the hardcoded default.

Key changes:

  • New epoch/context_keys.go with helper functions for storing/retrieving captured field values from Gin context
  • Modified version_change_builder.go to capture field values before RemoveField operations and restore them before AddField operations
  • Added legacy_notes field to the advanced example to demonstrate the feature
  • Added thread-safe mutexes to example storage

Motivation

Previously, when using RemoveField on a request type followed by AddField on a response type (a common pattern for deprecating fields), the response would always use the hardcoded default value. This meant that if a v1 client sent a value for a deprecated field, that value would be lost in the round-trip transformation.

This change enables seamless round-trip preservation of deprecated fields. A v1 client can send legacy_notes: "Important data" in a request, have it removed during request migration (so the handler doesn't see it), but have the original value restored in the response—not the default empty string.

Issue(s)

Fixes #81
https://linear.app/astronomer/issue/CPP-242/epoch-auto-capture-fields-for-addfieldremovefield

Functional Testing

  • added unit and integration tests

Manual Testing

Tested against examples/advanced/main.go:

Test 1: V2 GET existing user - legacy_notes passes through from storage

curl -H 'X-API-Version: 2024-06-01' http://localhost:8087/users/1
{"id":1,"email":"alice@example.com","status":"active","profile":{"bio":"Senior software engineer with 10 years of experience","skills":[{"name":"Go","level":5},{"name":"Python","level":4},{"name":"Kubernetes","level":3}],"settings":{"theme":"dark"}},"legacy_notes":"Original v1 user - migrated from legacy system","name":"Alice Johnson"}

Test 2: V1 POST without legacy_notes - uses default empty string

curl -X POST -H 'X-API-Version: 2024-01-01' -H 'Content-Type: application/json' \
  -d '{"name":"No Notes Test"}' \
  http://localhost:8087/users
{"id":3,"name":"No Notes Test","legacy_notes":""}

Test 3: V2 GET newly created user - no legacy_notes (field wasn't provided or stored)

curl -H 'X-API-Version: 2024-06-01' http://localhost:8087/users/3
{"id":3,"email":"unknown@example.com","status":"active","name":"No Notes Test"}

Test 4: V1 POST with legacy_notes - value PRESERVED in response

curl -X POST -H 'X-API-Version: 2024-01-01' -H 'Content-Type: application/json' \
  -d '{"name":"Auto Capture Test","legacy_notes":"Important notes from v1 client"}' \
  http://localhost:8087/users
{"id":5,"name":"Auto Capture Test","legacy_notes":"Important notes from v1 client"}

Screenshots

N/A

Checklist

  • Added/updated applicable tests
  • Added/updated examples in the examples/ directory
  • Updated any related documentation

@ichung08 ichung08 self-assigned this Jan 28, 2026
@ichung08 ichung08 linked an issue Jan 28, 2026 that may be closed by this pull request
@ichung08 ichung08 marked this pull request as ready for review January 28, 2026 01:26
@ichung08 ichung08 requested a review from a team as a code owner January 28, 2026 01:26
@ichung08 ichung08 merged commit be8893d into main Jan 28, 2026
2 checks passed
@ichung08 ichung08 deleted the 81-auto-capture-fields-for-addfieldremovefield branch January 28, 2026 21:47
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.

Auto-Capture Fields for AddField/RemoveField

3 participants