Skip to content

Conversation

@raphael
Copy link
Member

@raphael raphael commented Dec 26, 2025

Summary

This PR contains two bug fixes:

1. mains: Fix websocket import detection for server mains

The mains plugin was using httpcodegen.NeedDialer() to detect websocket usage, but that function is designed for client dialers, not servers. This caused the github.com/gorilla/websocket import to be missing when websocket.Upgrader was emitted in the generated main.

Fix: Use httpWebSocketByService() to detect streaming endpoints that require websocket support, matching the same detection used for HasAnyWebSocket in the template.

2. testing: Fix type assertion for ArrayOf results in ScenarioRunner (#234)

The testing plugin was generating invalid Go for array results in ScenarioRunner.callValidator, producing code like:

typedResult := result.(*bff.[]*AccessControl)  // ❌ Invalid Go

instead of the correct:

typedResult := result.([]*bff.AccessControl)   // ✅ Valid Go

This was caused by hardcoding the assertion shape as result.(*{{Pkg}}.{{Result}}), which breaks for composite types like ArrayOf(...).

Fix: Use Goa's GoFullTypeRef to compute the properly qualified type reference (handling *, [], map[...], etc.) and store it in a new ResultTypeRef field on scenarioMethodData.

Testing

  • All existing tests pass (go test ./...)
  • Added regression test TestGenerateScenarios_ArrayResultTypeAssertion to ensure the ArrayOf type assertion fix never regresses
  • Fixed TestWebSocketMainIncludesUpgrader to check the correct section for the websocket import

Fixes #234

This change enhances the mains plugin to support gRPC servers in addition to HTTP servers, addressing issue #209.

Key changes:
- Only generate HTTP server code when the service design includes HTTP endpoints
- Only generate gRPC server code when the service design includes gRPC endpoints
- Always generate the metrics HTTP server (health/metrics/debug endpoints)
- Fix duplicate package/import declarations in generated main.go
- Fix WebSocket detection bug (Stream value of 0 means no streaming, not NoStreamKind)
- Conditionally import transport-specific packages based on what's actually used
- Add proper OTel instrumentation for gRPC servers
- Implement graceful shutdown for both HTTP and gRPC servers

The plugin now:
1. Scans the DSL for HTTP and gRPC endpoint definitions
2. Conditionally generates server initialization code based on transports used
3. Manages imports efficiently (only includes websocket, grpc packages when needed)
4. Provides a unified main.go that can run HTTP-only, gRPC-only, or both transports
5. Maintains the existing single-service (services/<svc>/cmd/<svc>) and multi-service (cmd/<server>) layouts

Fixes #209
The testing plugin was generating invalid Go for array results in
ScenarioRunner.callValidator, producing code like:

    typedResult := result.(*bff.[]*AccessControl)

instead of the correct:

    typedResult := result.([]*bff.AccessControl)

This was caused by hardcoding the assertion shape as
`result.(*{{Pkg}}.{{Result}})`, which breaks for composite types.

Fix: Use Goa's GoFullTypeRef to compute the properly qualified type
reference (handling *, [], map[...], etc.) and store it in a new
ResultTypeRef field on scenarioMethodData.

Added regression test to ensure this pattern never recurs.
The mains plugin was using httpcodegen.NeedDialer() to detect websocket
usage, but that function is designed for client dialers, not servers.
This caused the github.com/gorilla/websocket import to be missing when
websocket.Upgrader was emitted in the generated main.

Fix: Use httpWebSocketByService() to detect streaming endpoints that
require websocket support, matching the same detection used for
HasAnyWebSocket in the template.

Also fixed the test to check the websocket import in the correct section
(source-header) rather than the main body section.
Goa v3.23.4 renamed Schema.Definitions to Schema.Defs to align with
JSON Schema draft 2020-12 which uses $defs instead of definitions.

Changes:
- Update dupSchema() to use Defs field instead of Definitions
- Update inlineRefs() to handle both #/$defs/ and #/definitions/ prefixes
- Update go.mod to require goa v3.23.4
- Regenerate golden files with new $ref format
Resolve conflicts by:
- Taking origin/v3 file server support (FSCounts, FileServerNils)
- Keeping websocket detection fix using httpWebSocketByService()
- Keeping test fix to check import in source-header section
@raphael raphael merged commit 105f10e into v3 Dec 26, 2025
5 checks passed
@raphael raphael deleted the feat/mains-grpc-support branch December 26, 2025 16:56
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.

testing plugin: syntax error in ScenarioRunner code

2 participants