Lessons Learned from Building Teamwork Desk Services with Go

This article shares practical lessons and common pitfalls encountered while developing numerous Go‑based microservices for Teamwork Desk, covering topics such as framework choices, panic handling, request body reuse, SQL handling, pointer usage, naked returns, variable shadowing, concurrent map access, and vendoring best practices.

High Availability Architecture
High Availability Architecture
High Availability Architecture
Lessons Learned from Building Teamwork Desk Services with Go

Teamwork's senior engineer Peter Kelly reflects on writing nearly 200,000 lines of Go code for more than a dozen HTTP services, explaining why Go's speed, strong concurrency model, and standard library make it ideal for web applications.

The team advises against using heavyweight MVC frameworks like Revel, preferring the standard library with lightweight routers and middleware, as Revel interferes with Go's tooling and build process.

They discuss proper panic handling, recommending recovery middleware that logs stack traces and reports to Sentry instead of allowing panics to crash the entire server.

When reading http.Request.Body, the body is exhausted; the article suggests buffering the body for repeated reads, noting the performance cost for large payloads.

For data access, the team uses Gorm's chainable API while still writing raw SQL when needed, emphasizing that Gorm can simplify queries without becoming a full‑blown ORM.

Common pointer misuse is highlighted, especially with slices, explaining that slices already contain a pointer and passing them by value is cheap, so extra pointer indirection is often unnecessary.

Naked (unnamed) returns are acceptable in small functions but can harm readability in larger ones; the article warns against multiple return points without clear naming.

Variable shadowing with the := operator can introduce subtle bugs; declaring variables outside the block and using = avoids this issue.

Concurrent map access is unsafe and can cause panics; wrapping maps with sync.RWMutex or using concurrent‑safe structures prevents crashes.

The importance of proper vendoring is covered, describing the evolution of Go's vendor support from Go 1.4 to 1.6 and recommending the use of a /vendor directory to lock dependencies.

Finally, the team summarizes their learning journey, invites developers to join Teamwork, and shares links to open‑source contributions.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

BackendconcurrencyError Handlingbest-practices
High Availability Architecture
Written by

High Availability Architecture

Official account for High Availability Architecture.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.