Phase 05 Plan 02: Nullable Encoding Summary
Nullable primitive support across all 4 generators: Go MarshalJSON/UnmarshalJSON with null emission, TypeScript T | null types, OpenAPI 3.1 type array syntax
Performance#
- Duration: 7 min
- Started: 2026-02-06T09:47:22Z
- Completed: 2026-02-06T09:54:26Z
- Tasks: 3
- Files modified: 19
Accomplishments#
- Go generators (httpgen + clientgen) generate MarshalJSON that emits
"field": nullfor unset nullable fields, and UnmarshalJSON that accepts null - TypeScript generator produces
fieldName: T | nullfor nullable fields (not optional?) - OpenAPI generator produces
type: ["T", "null"]per OpenAPI 3.1 spec - Golden file tests added for all 4 generators with zero regression on existing tests
- Validation errors for invalid nullable annotations (non-optional fields, message fields) propagated correctly
Task Commits#
Each task was committed atomically:
- Task 1: Implement nullable in Go generators -
74116e0(feat) - Task 2: Implement nullable in TypeScript and OpenAPI generators -
b98bb86(feat) - Task 3: Add nullable test proto and golden file tests -
21c719c(test)
Files Created/Modified#
internal/httpgen/nullable.go- MarshalJSON/UnmarshalJSON generation for nullable fields (go-http)internal/clientgen/nullable.go- Identical implementation for go-client consistencyinternal/httpgen/generator.go- Calls generateNullableEncodingFileinternal/clientgen/generator.go- Calls generateNullableEncodingFile before service checkinternal/tsclientgen/types.go- Nullable field detection withT | nulltype generationinternal/openapiv3/types.go- makeNullableSchema helper for type array syntaxinternal/httpgen/testdata/proto/nullable.proto- Test proto with nullable string, int32, bool fields- Golden files for httpgen, clientgen, tsclientgen, openapiv3 (7 golden files total)
- Test cases added to all 4 golden test files
Decisions Made#
- D-05-02-01: Identical nullable.go in httpgen and clientgen ensures server/client JSON consistency (same pattern as int64 encoding)
- D-05-02-02: Nullable TypeScript fields use
T | null(not optional?) because nullable fields are always present - they have either a value or null, never absent - D-05-02-03: OpenAPI 3.1 type array syntax
["T", "null"]used instead of the deprecatednullable: truefrom OpenAPI 3.0 - D-05-02-04: Nullable encoding generation placed before the service existence check in clientgen, matching httpgen pattern, so message-only proto files can still get nullable encoding
Deviations from Plan#
None - plan executed exactly as written.
Issues Encountered#
- Pre-existing
empty_behavior.gofile from a previous interrupted session causes lint warnings (11 unused + 1 exhaustive). This is untracked code not part of the nullable plan and was not committed. It will be addressed in a future plan (05-03 or later).
User Setup Required#
None - no external service configuration required.
Next Phase Readiness#
- Nullable encoding complete across all generators with full test coverage
- Ready for 05-03 (empty_behavior implementation) or 05-04 (cross-generator consistency tests)
- The pre-existing empty_behavior.go skeleton in httpgen needs to be either completed or removed in its own plan
Phase: 05-json-nullable-empty Completed: 2026-02-06
