I decided to try Go by building a CRUD API for a new project. My recent background was primarily Java, Groovy, and Python, so the project was both a practical prototype and a deliberate learning exercise.
Why this still matters
Learning a new language through a real system exposes tradeoffs that tutorials often hide. The same approach is useful today when evaluating Go for APIs, cloud services, and resource-constrained systems: define the operational requirements first, then let the language and libraries prove themselves against them.
Requirements
The project needed to:
- Define a data model for a domain
- Implement a CRUD API
- Use MongoDB as the persistence layer
- Publish a Swagger definition for documentation and client generation
- Run in a Docker container
- Remain deployable to Kubernetes
It also needed to be easy for clients written in other languages to consume, move quickly during experimentation, and include unit tests.
A useful constraint was conservative memory consumption so the service could eventually run in a constrained environment such as a Raspberry Pi.
Libraries
The project used focused libraries for the main concerns:
| Area | Library |
|---|---|
| Database access | mongo-go-driver |
| Routing | go-chi |
| JSON Patch | json-patch |
| Unit tests | testify |
| API definition | go-swagger |
Development experience
Go was approachable because its syntax felt familiar coming from C and Java. I liked the simplicity and clarity of the code, along with the explicitness of its standard patterns.
Error handling required an adjustment. Instead of relying on exceptions, Go makes the caller inspect and pass errors explicitly:
value, err := doSomething()
if err != nil {
log.Println("operation failed:", err)
return err
}
That can feel repetitive, but it makes failure paths visible. JSON handling also required care: mapping dynamic responses into statically typed structs is more deliberate than working with maps in Python or Groovy.
Conclusion
It was surprisingly easy to become productive in Go through a small but complete project. Refining the API, data model, Swagger documentation, and tests made the language feel practical and pleasant, and gave me a strong reason to continue learning it.