Releases: goadesign/goa
Goa v3.25.3
Highlights
- Fixes a code generation regression where HTTP request decoders for primitive payloads (e.g.
string,bool, numeric types) could emit invalid early returns (return nil, err) on validation/decode errors. - Prevents downstream build failures such as
cannot use nil as string value in return statementfor designs using primitive payloads with validations (e.g.Format(FormatIP)on path params). - Adds regression coverage, including a golden-backed case for
Format(FormatIP)validation on a primitive path payload.
What's Changed
Full Changelog
Goa v3.25.2
Highlights
- Fixes code generation for
OneOfprimitive aliases when service types are emitted to custom packages viastruct:pkg:path. - Prevents
undefined: Value*compile errors in generated service code for affected designs. - Adds regression coverage for nested types and JSON-tagged field variants to prevent this from reappearing.
What's Changed
Full Changelog
Goa v3.25.1
Highlights
- HTTP route tagging fix (otelhttp): v3.25.1 completes the
r.Patternroute tagging work from v3.25.0 sootelhttp(v0.65.0+) reliably records thehttp.routespan attribute and metric route when used as a mux middleware (mux.Use(otelhttp.NewMiddleware(...))). (#3898) - Better DSL error messages: validation errors include
file:linelocations pointing to the offending design declaration, making it much faster to find and fix issues in large Goa designs. (#3895) - Mixed unary + SSE results: services can define both a unary
Resultand aStreamingResulton the same method with distinct types — the generated HTTP handler performs content negotiation based on theAcceptheader. (#3883)
What changed
HTTP runtime
r.Patternauto-populated (and visible to middlewares): the default muxer captures the original Goa route pattern (before Chi wildcard rewriting) and setsr.Pattern = "METHOD /path"following the Go 1.22+ convention. v3.25.1 ensures this happens early enough that middlewares registered viaUse()(includingotelhttp.NewMiddleware) can readr.Patternat span-start time to populate thehttp.routeattribute. (#3897, #3898)
Eval / DSL
- Validation error locations:
Validate()-phase errors now derivefile:linefrom the expression's DSL function pointer usingruntime.CallersFrames, robust to inlining. Both DSL-time and validation-time errors benefit. (#3895, #3890)
Codegen
- Mixed unary + SSE: generated handlers perform
Accept-based content negotiation; the generated client exposes a split API (Methodfor unary,MethodStreamfor SSE). A non-nil discard stream implementation is passed in unary mode so service code can use the stream parameter without nil guards. (#3883) - OneOf in ResultType views: union helper types are now emitted in the
viewspackage when referenced by view-projected types, fixing build failures forOneOfinsideResultType. (#3884) - Composite client response decoding: unnamed array/map HTTP client response bodies now decode directly into the concrete wire type instead of generating endpoint-scoped wrapper aliases, fixing build failures when multiple endpoints share a structural type. (#3888)
- WebSocket upgrade error persistence: upgrade failures are now stored on the server stream struct so subsequent
Send/Recvcalls reliably return the error instead of panicking on a nil connection. (#3885) - HTTP client array payload codegen: fixed deduplication of request body builder functions when multiple methods use
ArrayOf(...)payloads with different element types. (#3879)
Upgrade notes
This release changes generated code. After upgrading, regenerate and review the diff:
go get goa.design/goa/v3@v3.25.1
# then run your normal generation flow (goa gen / go generate)OpenTelemetry route tagging
-
Recommended: register
otelhttpas a mux middleware so it can readr.Patternat span-start time:mux := goahttp.NewMuxer() mux.Use(otelhttp.NewMiddleware("service"))
-
If you wrap the mux externally with
otelhttp.NewHandler(mux, ...),otelhttpstarts the span before it calls into the mux, sor.Patternis not available at span-start. In that setup, use theotelplugin (it setshttp.routedirectly on the active span inside each generated handler).
Full changelog
- #3898 http: set r.Pattern in ServeHTTP before middleware dispatch
- #3879 fix: http client codegen for multiple array-type payloads
- #3883 codegen: support mixed unary + SSE results
- #3884 codegen: generate OneOf unions in views package
- #3885 http/codegen: persist websocket upgrade errors
- #3888 http/codegen: decode composite client responses without wrappers
- #3890 eval: report validation error locations
- #3895 eval: report validation error locations (refinement)
- #3897 http: set r.Pattern on dispatched requests for automatic route tagging
Compare: v3.25.0...v3.25.1
Goa v3.25.0
Highlights
- Automatic HTTP route tagging: the default Goa muxer now sets
r.Patternon every dispatched request, enabling observability middleware likeotelhttp(v0.65.0+) to tag spans and metrics with the matched route automatically — no per-handler wrapping or plugin required. (#3897) - Better DSL error messages: validation errors now include
file:linelocations pointing to the offending design declaration, making it much faster to find and fix issues in large Goa designs. (#3895) - Mixed unary + SSE results: services can now define both a unary
Resultand aStreamingResulton the same method with distinct types — the generated HTTP handler performs content negotiation based on theAcceptheader. (#3883)
What changed
HTTP runtime
r.Patternauto-populated: the muxer captures the original Goa route pattern (before Chi wildcard rewriting) and setsr.Pattern = "METHOD /path"following the Go 1.22+ convention. This is a single, uniform hook that covers all handlers — endpoints and file servers alike. Theotelplugin has been deprecated in favor of this built-in mechanism. (#3897)
Eval / DSL
- Validation error locations:
Validate()-phase errors now derivefile:linefrom the expression's DSL function pointer usingruntime.CallersFrames, robust to inlining. Both DSL-time and validation-time errors benefit. (#3895, #3890)
Codegen
- Mixed unary + SSE: generated handlers perform
Accept-based content negotiation; the generated client exposes a split API (Methodfor unary,MethodStreamfor SSE). A non-nil discard stream implementation is passed in unary mode so service code can use the stream parameter without nil guards. (#3883) - OneOf in ResultType views: union helper types are now emitted in the
viewspackage when referenced by view-projected types, fixing build failures forOneOfinsideResultType. (#3884) - Composite client response decoding: unnamed array/map HTTP client response bodies now decode directly into the concrete wire type instead of generating endpoint-scoped wrapper aliases, fixing build failures when multiple endpoints share a structural type. (#3888)
- WebSocket upgrade error persistence: upgrade failures are now stored on the server stream struct so subsequent
Send/Recvcalls reliably return the error instead of panicking on a nil connection. (#3885) - HTTP client array payload codegen: fixed deduplication of request body builder functions when multiple methods use
ArrayOf(...)payloads with different element types. (#3879)
Upgrade notes
This release changes generated code. After upgrading, regenerate and review the diff:
go get goa.design/goa/v3@v3.25.0
# then run your normal generation flow (goa gen / go generate)The otelhttp route-tagging behavior is automatic for the default Goa muxer — if you were using the otel plugin solely for WithRouteTag, you can remove it.
Full changelog
- #3879 fix: http client codegen for multiple array-type payloads
- #3883 codegen: support mixed unary + SSE results
- #3884 codegen: generate OneOf unions in views package
- #3885 http/codegen: persist websocket upgrade errors
- #3888 http/codegen: decode composite client responses without wrappers
- #3890 eval: report validation error locations
- #3895 eval: report validation error locations (refinement)
- #3897 http: set r.Pattern on dispatched requests for automatic route tagging
Compare: v3.24.3...v3.25.0
Goa v3.24.3
Highlights
- Codegen (views/OneOf): fix generated examples when a
ResultTypecontains aOneOf(union) field by emitting the required union helpers in theviewspackage. (#3884) - Codegen (mixed unary + SSE): support services that expose both unary and SSE streaming results cleanly. (#3883)
- HTTP client codegen: fixes and improvements to the generated HTTP client. (#3879)
Full changelog
- Compare:
v3.24.2...v3.24.3
Goa v3.24.2
Highlights
- Codegen correctness for union transforms: sum-type union object branches now use the generated per-type helper transforms, avoiding branch-local inline conversions that could disagree on details (notably nested map key casts). (#3880)
- Qualified type refs are now stable and real: transport codegen no longer “suffixes” the
Typeportion ofpkg.Typerefs (preventing invalid refs likepkg.Foo2), while still reusing the scoped name when the service scope had to suffix due to collisions. (#3878) - Union validation pointer semantics fixed: sum-type union branch validation now derives pointer/value semantics from the branch value (esp. object branches) rather than the enclosing field context. (#3876)
Metais now extensible for plugins: introducedexpr.MetaAdder/expr.MetaDeleter, shrinkingdsl.Meta/RemoveMetaand enabling third-party expressions to participate without Goa knowing their concrete types; also fixes an OpenAPI regression where host metadata could attach to host variables. (#3874)
What changed
Codegen / transforms
- Union object branches:
GoTransformnow prefers helper transforms for object branches in sum-type unions, improving consistency and preventing subtle type mismatches. (#3880) - Name scoping across packages: qualified refs now respect scoping rules without inventing external identifiers; transport packages that reference suffixed service types will correctly reference the suffixed name. (#3878)
Validation + gRPC
- Sum-type union validation now matches the actual generated union field shapes (value vs pointer). (#3876)
- gRPC union member shape validation moved out of
AttributeExpr.Validateinto gRPC endpoint validation with recursion guards (more correct layering, fewer surprise validations). (#3876)
DSL / expr
- Added
expr.MetaAdder/expr.MetaDeleterand wired core expressions + attributes into them;dsl.Meta/RemoveMetanow dispatch via these interfaces (and still supportsCompositeExprcorrectly). (#3874)
Upgrade notes
- Regenerate: this release changes generated code shape in union transforms and may affect transport packages with scoped type collisions. After upgrading, run your normal regeneration flow (e.g.
goa gen/go generate), then review the diff.
go get goa.design/goa/v3@v3.24.2Full changelog
- #3874 dsl/meta: make Meta extensible via expr.MetaAdder
- #3876 codegen: fix union-sum validation pointer semantics
- #3878 codegen: reuse scoped names for qualified refs
- #3880 codegen: use helper transforms for union object branches
Compare: v3.24.1...v3.24.2
v3.24.1
Goa v3.24.1
Highlights
-
Fix: unions + custom
struct:pkg:pathnow generate valid codev3.24.0 introduced generated JSON marshalers for union sum types. When a union (or a type containing a union) was generated into a separate file via
Meta("struct:pkg:path", ...), the generated file could miss the requiredencoding/jsonimport, causing compile failures.v3.24.1 fixes this by ensuring service codegen
struct:pkg:path“User types” files include the JSON import.
Changelog
- Fixed: missing
encoding/jsonimport for union sum types generated intostruct:pkg:pathfiles. - Added: regression test to prevent this from happening again.
Previously in v3.24.0 (included here so you don’t miss it)
Highlights (read this first)
-
Breaking:
OneOfunions are now generated as first-class sum types across Goa codegen (service types + HTTP client/server types), with a discriminator (Kind) and typed constructors/accessors/setters. This is a major ergonomics + correctness upgrade, but it will break existing code that used the old interface-based union representation.See PR #3866: “Redesign OneOf unions as first-class sum types”.
Breaking Changes
-
Breaking: Union/
OneOfgenerated Go API changed (regen required). (PR #3866)- Before: unions were represented as an interface with marker methods (e.g.
interface{ valuesVal() }) and consumed viaswitch x := u.(type) { ... }. - Now: unions are generated as a concrete sum-type struct with:
Kind()discriminatorNew<Union><Branch>(...)constructorsAs<Branch>() (v, ok)accessorsSet<Branch>(...)settersValidate()+ JSON{type,value}MarshalJSON/UnmarshalJSON
- Migration checklist:
- Regenerate (
goa gen ...) - Replace type-switches with
switch u.Kind()/u.AsXxx() - Replace direct assignment of branch types with
New.../Set...
- Regenerate (
- Before: unions were represented as an interface with marker methods (e.g.
-
Breaking: gRPC
Anynow maps togoogle.protobuf.Value(structpb.Value) instead ofgoogle.protobuf.Any. (PR #3868)This changes the generated proto surface; regenerate and update non-Go clients accordingly.
Notable Additions
-
Union JSON key customization:
Meta("oneof:type:field", "...")andMeta("oneof:value:field", "...")let you rename the canonical{type,value}keys for union JSON encoding (e.g.{kind,data}), with DSL-level validation.Included as part of the union redesign work; see PR #3866.
-
struct:tag:json:namemeta: set a JSON field name without having to override the fulljsontag; Goa still computesomitemptyproperly. (PR #3867)
Dependency Updates
v3.23.4
What's Changed
Bug Fixes
-
eval: Fix error location for module cache paths (#3861)
When Goa is consumed from the Go module cache, file paths contain
@versionsegments (e.g.,goa/v3@v3.23.2/dsl/...). The error location heuristic was failing to recognize these as DSL frames, causing errors to point at internal DSL files rather than the user's design.Error messages now correctly show:
[design.go:5] invalid use of View in type "SomeType"instead of:
[.../dsl/result_type.go:215] invalid use of View in attribute -
http: Preserve Content-Type parameters set in DSL (#3860)
Fixes an issue where Content-Type parameters specified in the DSL were being dropped.
-
codegen: Skip example generation for agent-only designs (#3858)
Fixes crashes when running
goa exampleon designs that only define agents (no HTTP/gRPC transports).
New Features
-
grpc/codegen: Allow overriding proto
json_name(#3857)You can now customize the JSON field name in generated proto files.
Other Changes
Contributors
A huge thank you to our contributors for this release:
Full Changelog: v3.23.3...v3.23.4