Command Line Tool
Learn about Goa’s command-line tool for code generation, including installation, usage, and best practices.
Goa’s code generation system transforms your design into production-ready code. Rather than just scaffolding, Goa generates complete, runnable service implementations that follow best practices and maintain consistency across your entire API.
Goa’s code generation takes your design files and produces complete, runnable service implementations.
Install Goa’s command-line tools using:
go install goa.design/goa/v3/cmd/goa@latest
Goa provides two commands to help you generate and scaffold your services. All commands expect a Go package import path, not a filesystem path:
# ✅ Correct: using Go package import path
goa gen goa.design/examples/calc/design
# ❌ Incorrect: using filesystem path
goa gen ./design
goa gen
)goa gen <design-package-import-path> [-o <output-dir>]
The primary command for code generation. It:
gen/
directory from scratch each time-o
flag (defaults to ./gen
)goa example
)goa example <design-package-import-path> [-o <output-dir>]
A scaffolding command that:
goa version
)goa version
Displays the installed version of Goa.
When you run the Goa code generation commands, Goa follows a systematic process to transform your design into working code:
The generation process happens in several phases:
Bootstrap:
First, Goa creates a temporary main.go
file that imports your design
package and the Goa packages. This temporary file is then compiled and
executed as a separate process to bootstrap the code generation.
DSL Execution: The design package’s initialization functions execute first, followed by the DSL functions which construct expression objects in memory. These expressions work together to create a comprehensive model representing your entire API design.
Validation: During validation, Goa performs comprehensive checks on the expression tree to ensure it is complete and well-formed. It verifies that all required relationships between expressions are properly defined and that the design follows all rules and constraints. This validation step helps catch potential issues early in the development process before any code is generated.
Code Generation:
Once validation is complete, Goa passes the valid expressions to the code
generators. These generators use the expression data to render templates,
which produce the actual code files. The generated files are then written to
the gen/
directory in your project, organized by service and transport
layer.
The Meta
function allows you to customize code generation behavior. Here are
key metadata tags that affect generation:
The "type:generate:force"
tag can be used to force the generation of a type
even if it is not directly referenced by any method. The values are the names
of the services that need the type generated.
var MyType = Type("MyType", func() {
// Force type generation even if unused
Meta("type:generate:force", "service1", "service2")
Attribute("name", String)
})
The "struct:pkg:path"
tag allows you to specify the package and path for a
type. The values is the package path relative to the gen
package.
var MyType = Type("MyType", func() {
// Generate type in custom package
Meta("struct:pkg:path", "types")
Attribute("ssn", String, func() {
// Override field name
Meta("struct:field:name", "SSN")
// Custom struct tags
Meta("struct:tag:json", "ssn,omitempty")
})
})
The "struct:name:proto"
tag allows you to specify the name of the protocol
buffer message for a type. The values are the package path, the message name,
and the import path of the protocol buffer type.
var Timestamp = Type("Timestamp", func() {
// Override protobuf message name
Meta("struct:name:proto", "MyProtoType")
Field(1, "created_at", String, func() {
// Use Google's timestamp type
Meta("struct:field:proto",
"google.protobuf.Timestamp",
"google/protobuf/timestamp.proto",
"Timestamp",
"google.golang.org/protobuf/types/known/timestamppb")
})
})
The "openapi:generate"
tag allows you to disable OpenAPI generation for a
service. The values are the names of the services that need the type generated.
The "openapi:operationId"
tag allows you to specify the operation ID for a
method. The values are the service name and the method name.
The "openapi:tag"
tag allows you to specify the OpenAPI tags for a service.
The values are the service name and the tag name.
var _ = Service("MyService", func() {
// Disable OpenAPI generation for this service
Meta("openapi:generate", "false")
Method("MyMethod", func() {
// Custom operation ID
Meta("openapi:operationId", "{service}.{method}")
// Add OpenAPI tags
Meta("openapi:tag:Backend", "Backend API")
})
})
Common metadata uses:
type:generate:force
when types are only referenced indirectlystruct:pkg:path
) consistent across related typesGoa’s plugin system allows you to extend and customize the code generation process. Plugins intercept the generation pipeline at specific points, enabling you to add features, modify generated code, or create entirely new outputs.
Plugins can interact with Goa in three main ways:
var _ = Service("calc", func() {
Description("Calculator service")
// CORS plugin adds this DSL
cors.Origin("/.*localhost.*/", func() {
cors.Headers("X-Shared-Secret")
cors.Methods("GET", "POST")
})
})
Modify Generated Code
Plugins can inspect and modify the files Goa generates, or add new files
entirely: The plugin Generate
function is called by Goa during code
generation after the design has been evaluated. It receives:
genpkg
: The Go package path where generated code will be placedroots
: The evaluated design roots containing all design datafiles
: The array of files that Goa has generated so farThis function allows plugins to inspect and modify any generated files, add entirely new files to the output, remove files from generation, and transform code based on the design. The flexibility of this function enables plugins to have complete control over the final generated codebase.
Plugins are typically used to:
To use an existing plugin:
goa gen
as usual - the plugin automatically integratesimport (
. "goa.design/goa/v3/dsl"
cors "goa.design/plugins/v3/cors/dsl"
)
This is just an overview of Goa’s plugin system. For detailed information about:
See the dedicated Plugins section.