feat: auto capture fields for add and remove field #82
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Description
Add automatic field capture for
RemoveFieldandAddFieldversion change operations. When a field is removed from a request during version migration, its value is now automatically captured in the Gin context. WhenAddFieldis used in the response migration for the same field name, the captured value is restored instead of using the hardcoded default.Key changes:
epoch/context_keys.gowith helper functions for storing/retrieving captured field values from Gin contextversion_change_builder.goto capture field values beforeRemoveFieldoperations and restore them beforeAddFieldoperationslegacy_notesfield to the advanced example to demonstrate the featureMotivation
Previously, when using
RemoveFieldon a request type followed byAddFieldon 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
Manual Testing
Tested against
examples/advanced/main.go:Test 1: V2 GET existing user -
legacy_notespasses through from storagecurl -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{"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{"id":5,"name":"Auto Capture Test","legacy_notes":"Important notes from v1 client"}Screenshots
N/A
Checklist
examples/directory