Ready to build something awesome? This guide assumes you have curl
installed. Any other HTTP client will work as well.
Let’s start our journey by setting up a fresh workspace for your first Goa service:
mkdir hello-goa && cd hello-goa
go mod init hello
Note: While we’re using a simple module name
hello
for this guide, in real-world projects you’d typically use a domain name likegithub.com/yourusername/hello-goa
. Don’t worry - the concepts you’ll learn work exactly the same way!
Now comes the exciting part - designing your service! Goa’s powerful DSL will help you create a clean, professional API in just a few lines of code.
design
Foldermkdir design
design/design.go
):package design
import (
. "goa.design/goa/v3/dsl"
)
var _ = Service("hello", func() {
Description("A simple service that says hello.")
Method("sayHello", func() {
Payload(String, "Name to greet")
Result(String, "A greeting message")
HTTP(func() {
GET("/hello/{name}")
})
})
})
Let’s break down what this design does:
Service("hello", ...)
defines a new service named “hello”sayHello
that:Payload
- this will be the name we want to greetResult
- our greeting message/hello/{name}
where {name}
will be automatically bound to our payloadThis simple design showcases Goa’s declarative approach - we describe what we want our API to do, and Goa handles all the implementation details like parameter binding, routing, and OpenAPI documentation.
Here’s where the magic happens! Let’s use Goa’s code generator to transform your design into a fully functional service structure:
goa gen hello/design
This creates a gen
folder containing everything you need - endpoints, transport logic, and even
OpenAPI specs. Pretty cool, right?
Now, let’s scaffold a working service with the example
command:
goa example hello/design
Note: Think of the
example
command as your starting point - it gives you a working implementation that you can build upon. While you’ll re-rungen
when your design changes, the code fromexample
is yours to customize and enhance.
Here’s what you’ll find in your hello-goa
folder:
hello-goa
├── cmd
│ ├── hello
│ │ ├── http.go
│ │ └── main.go
│ └── hello-cli
│ ├── http.go
│ └── main.go
├── design
│ └── design.go
├── gen
│ ├── ...
│ └── http
└── hello.go
Time to bring your service to life! Edit the hello.go
file and replace the
SayHello
method with this welcoming implementation:
func (s *hellosrvc) SayHello(ctx context.Context, name string) (string, error) {
log.Printf(ctx, "hello.sayHello")
return fmt.Sprintf("Hello, %s!", name), nil
}
You’re almost there - and wasn’t that surprisingly simple?
First, let’s get all our dependencies in order:
go mod tidy
Now for the moment of truth - let’s bring your service online:
go run hello/cmd/hello --http-port=8080
INFO[0000] http-port=8080
INFO[0000] msg=HTTP "SayHello" mounted on GET /hello/{name}
INFO[0000] msg=HTTP server listening on "localhost:8080"
Open a new terminal and let’s see your service in action:
curl http://localhost:8080/hello/Alice
"Hello, Alice!"
🎉 Amazing! You’ve just created and deployed your first Goa service. This is just the beginning of what you can build with Goa!
Want to try something even cooler? Goa automatically generated a command-line client for you. Give it a spin:
go run hello/cmd/hello-cli --url=http://localhost:8080 hello say-hello -p=Alice
Curious about what else the CLI can do? Check out all the features:
go run hello/cmd/hello-cli --help
As your service grows, you’ll want to add new features. Whenever you update your design with new methods, fields, or errors, just run:
goa gen hello/design
Your service code is yours to evolve - Goa won’t touch anything outside the gen
folder,
so feel free to enhance and customize to your heart’s content!
Ready to take your Goa skills to the next level? Dive into our Tutorials where you’ll learn to build powerful REST APIs, gRPC services, and much more. The possibilities are endless!