Skip to content

Releases: goadesign/goa

Goa v3.25.3

19 Feb 01:58
57351f1

Choose a tag to compare

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 statement for 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

  • Fix HTTP request decoder returns for primitive payloads by @raphael in #3901

Full Changelog

v3.25.2...v3.25.3

Goa v3.25.2

19 Feb 01:22
26e3d33

Choose a tag to compare

Highlights

  • Fixes code generation for OneOf primitive aliases when service types are emitted to custom packages via struct: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

  • codegen/service: fix primitive OneOf alias emission with struct:pkg:path by @raphael in #3900

Full Changelog

v3.25.1...v3.25.2

Goa v3.25.1

16 Feb 23:52
5b67239

Choose a tag to compare

Highlights

  • HTTP route tagging fix (otelhttp): v3.25.1 completes the r.Pattern route tagging work from v3.25.0 so otelhttp (v0.65.0+) reliably records the http.route span attribute and metric route when used as a mux middleware (mux.Use(otelhttp.NewMiddleware(...))). (#3898)
  • Better DSL error messages: validation errors include file:line locations 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 Result and a StreamingResult on the same method with distinct types — the generated HTTP handler performs content negotiation based on the Accept header. (#3883)

What changed

HTTP runtime

  • r.Pattern auto-populated (and visible to middlewares): the default muxer captures the original Goa route pattern (before Chi wildcard rewriting) and sets r.Pattern = "METHOD /path" following the Go 1.22+ convention. v3.25.1 ensures this happens early enough that middlewares registered via Use() (including otelhttp.NewMiddleware) can read r.Pattern at span-start time to populate the http.route attribute. (#3897, #3898)

Eval / DSL

  • Validation error locations: Validate()-phase errors now derive file:line from the expression's DSL function pointer using runtime.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 (Method for unary, MethodStream for 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 views package when referenced by view-projected types, fixing build failures for OneOf inside ResultType. (#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/Recv calls 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 otelhttp as a mux middleware so it can read r.Pattern at span-start time:

    mux := goahttp.NewMuxer()
    mux.Use(otelhttp.NewMiddleware("service"))
  • If you wrap the mux externally with otelhttp.NewHandler(mux, ...), otelhttp starts the span before it calls into the mux, so r.Pattern is not available at span-start. In that setup, use the otel plugin (it sets http.route directly 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


Thank you to @abocim for contributing #3879!

Goa v3.25.0

16 Feb 19:33
dffd5d0

Choose a tag to compare

Highlights

  • Automatic HTTP route tagging: the default Goa muxer now sets r.Pattern on every dispatched request, enabling observability middleware like otelhttp (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:line locations 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 Result and a StreamingResult on the same method with distinct types — the generated HTTP handler performs content negotiation based on the Accept header. (#3883)

What changed

HTTP runtime

  • r.Pattern auto-populated: the muxer captures the original Goa route pattern (before Chi wildcard rewriting) and sets r.Pattern = "METHOD /path" following the Go 1.22+ convention. This is a single, uniform hook that covers all handlers — endpoints and file servers alike. The otel plugin has been deprecated in favor of this built-in mechanism. (#3897)

Eval / DSL

  • Validation error locations: Validate()-phase errors now derive file:line from the expression's DSL function pointer using runtime.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 (Method for unary, MethodStream for 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 views package when referenced by view-projected types, fixing build failures for OneOf inside ResultType. (#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/Recv calls 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


Thank you to @abocim for contributing #3879!

Goa v3.24.3

07 Feb 06:14
d77d595

Choose a tag to compare

Highlights

  • Codegen (views/OneOf): fix generated examples when a ResultType contains a OneOf (union) field by emitting the required union helpers in the views package. (#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

01 Feb 22:02
290966e

Choose a tag to compare

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 Type portion of pkg.Type refs (preventing invalid refs like pkg.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)
  • Meta is now extensible for plugins: introduced expr.MetaAdder / expr.MetaDeleter, shrinking dsl.Meta/RemoveMeta and 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: GoTransform now 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.Validate into gRPC endpoint validation with recursion guards (more correct layering, fewer surprise validations). (#3876)

DSL / expr

  • Added expr.MetaAdder / expr.MetaDeleter and wired core expressions + attributes into them; dsl.Meta/RemoveMeta now dispatch via these interfaces (and still supports CompositeExpr correctly). (#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.2

Full 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

18 Jan 16:48
fd60b2d

Choose a tag to compare

Goa v3.24.1

Highlights

  • Fix: unions + custom struct:pkg:path now generate valid code

    v3.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 required encoding/json import, 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/json import for union sum types generated into struct:pkg:path files.
  • 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: OneOf unions 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/OneOf generated Go API changed (regen required). (PR #3866)

    • Before: unions were represented as an interface with marker methods (e.g. interface{ valuesVal() }) and consumed via switch x := u.(type) { ... }.
    • Now: unions are generated as a concrete sum-type struct with:
      • Kind() discriminator
      • New<Union><Branch>(...) constructors
      • As<Branch>() (v, ok) accessors
      • Set<Branch>(...) setters
      • Validate() + 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...
  • Breaking: gRPC Any now maps to google.protobuf.Value (structpb.Value) instead of google.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", "...") and Meta("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:name meta: set a JSON field name without having to override the full json tag; Goa still computes omitempty properly. (PR #3867)

Dependency Updates

v3.23.4

14 Dec 23:35
c5c2f7d

Choose a tag to compare

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 @version segments (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 example on 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

  • ci: Upgrade Go versions to 1.24 and 1.25 (#3859)
  • deps: Update module dependencies (#3862)

Contributors

A huge thank you to our contributors for this release:

Full Changelog: v3.23.3...v3.23.4

v3.23.2

26 Nov 21:41
ae9e54b

Choose a tag to compare

What's Changed

  • grpc: complete validation helper naming fix by @raphael in #3854

Full Changelog: v3.23.1...v3.23.2

v3.23.1

26 Nov 08:02
debd643

Choose a tag to compare

What's Changed

  • grpc: fix validation helper naming to match call sites by @raphael in #3853

Full Changelog: v3.23.0...v3.23.1