Skip to content

psaraiva/lab-cloud-native-dev

Repository files navigation

Combating Technical Debt: Immediate Setup & Productivity with Dev Containers in Go

Idioma: Português

This repository presents a development laboratory focused on solving Technical Debt and Setup Friction challenges within development teams, especially those dealing with legacy systems or shared, volatile infrastructure.

The core solution demonstrates how to standardize the development environment to ensure security, consistency, and high Developer Experience (DX) using modern tooling combined with Go code best practices.


🎯 The STAR Approach (Situation, Task, Action, Result)

1. 🧑‍💻 Situation (The Setup Problem)

The primary technical debt addressed is the difficulty in providing developers with a safe, easily accessible, and identical development environment. Legacy projects often demand specific, outdated versions of languages, system libraries, or third-party tools, making onboarding and daily development slow and frustrating.

2. 📝 Task (The Motivation)

Traditional paths to circumventing this friction (manual local environment configuration) are usually long, full of blocks (dependency on other teams), partial (the local environment is never 100% equal to production), and insecure (polluting the developer's host machine). Our goal is to eliminate this friction entirely.

3. 🛠️ Action (The Dev Container Solution)

Provide a Docker image strictly focused on development, containing all required dependencies, and couple it with the Dev Containers plugin (ms-vscode-remote.remote-containers) for Visual Studio Code.

This ensures:

  • Plug-and-Play: The developer clones the repo and starts coding in seconds.
  • Productivity (gopls): Use of the correct gopls (Language Server) version inside the container, guaranteeing intelligent, safe autocomplete, navigation, and refactoring features.
  • Seamless Debugging (delve): Ability to use the native VS Code debugger (delve) as if the code were running locally, but executing with the exact dependencies of the containerized environment.

4. ✅ Prerequisite (The Technique Result)

This environment technique is language-agnostic and only requires the presence of a package management file (e.g., go.mod for Go) and access to minimal environment configuration (e.g., environment variables, API URLs) to generate the development Docker image.


✨ Quality Standards in the Target Application

While the primary focus is the development environment, the target application code (cloud-native-dev-lab) adheres to advanced software engineering patterns to guarantee longevity and maintainability, minimizing future technical debt.

Strategic Development Environment (DX Focus)

  • 🐳 VS Code Dev Containers (Environment Consistency): The devcontainer.json configuration ensures that the developer automatically provisions an isolated workspace with the exact required legacy Go version.

  • ⚙️ Configuration Management Flexibility:

    • The devcontainer.json file allows for the passing of environment variables directly into the containerized development environment.
    • This enables the application's configuration to remain in an external layer, granting the flexibility to replicate production scenarios (Prod) in the development (Dev) environment securely and easily, adapting to various corporate needs.
  • 🧠 Optimized gopls for Legacy Code: The environment explicitly configures a compatible gopls version, guaranteeing modern IDE features for the legacy Go runtime.

  • 🐞 Seamless Debugging: The VS Code debugger integrates transparently with the Dev Container for a local machine experience.

Architectural Integrity (Decoupling)

  • Clean Architecture (Ports & Adapters): Business logic (the service package) is strictly decoupled from infrastructure details (the client package).
  • Typed Errors: The Adapter translates technical errors into Typed Go Errors (client.ErrNotFound). The Service Layer uses errors.Is() to identify the error and respond with a safe, standardized business status.
  • Context Propagation: Required use of context.Context to propagate timeout and cancellation signals throughout the execution chain.
  • Interface Design: Crucially, the Go Interface Design (Port) adheres to the Interface Segregation Principle (ISP). By defining a lean, intentional contract (PokemonProvider), we guarantee maximal testability and prevent the domain from depending on methods or data it doesn't strictly require.

🤖 Automation via Makefile

The Makefile serves as the crucial automation engine for the project. Its importance lies in standardizing common development and QA tasks, ensuring that every developer executes the same commands in the same way, whether locally or inside the Dev Container. This consistency is vital for reproducible quality assurance.

Makefile Target Description
make install Installs necessary Go tools (linters, static analyzers) within the environment.
make test Executes all unit tests with verbose output and coverage reporting.
make cover Opens the test coverage report in the browser for visual analysis.
make lint Runs all configured static analysis checks and linters (e.g., golangci-lint).
make build Compiles the Go application binary.
make clean Removes compiled binaries and intermediate files.

Cloud-Native Alignment (The Twelve-Factor App)

Even though architectural compliance was not the primary focus, the design decisions made (Go, containers, dependency injection) align the application with the essential principles of the Twelve-Factor App methodology. This ensures that, beyond the great Developer Experience, the resulting application is inherently scalable, portable, and resilient in a Cloud-Native environment.

Factor Project Status
I. Codebase Contemplated
II. Dependencies Contemplated
III. Configuration Contemplated
IV. Backing Services Implied
V. Build, Release, Run Implied
VI. Processes Implied
VII. Port Binding Implied
VIII. Concurrency Contemplated
IX. Disposability Contemplated
X. Dev/Prod Parity Contemplated
XI. Logs Partially
XII. Admin Processes N/A

SOLID Principles Compliance

The application's architecture (Ports & Adapters) and the disciplined use of Go Interfaces provide strong compliance with the fundamental object-oriented design principles (SOLID), resulting in highly maintainable and testable code.

Principle Project Status
Single Responsibility (SRP) Contemplated
Open/Closed (OCP) Contemplated
Liskov Substitution (LSP) Contemplated
Interface Segregation (ISP) Contemplated
Dependency Inversion (DIP) Contemplated

Testing

  • Test-Driven Error Validation: All components utilize Table-Driven Tests (TDT). Tests assert the type of error using errors.Is.
  • High Coverage: The implementation achieves 100% test coverage on the Adapter (client), validating the comprehensive error translation logic.

📝 Disclaimer & Contributions

This lab was constructed within a deliberately reduced and simplified context to illustrate core architectural concepts. Real-world scenarios will likely demand further configuration and alterations based on specific corporate standards, existing infrastructure, and operational nuances.

A Note on Quality Assurance (QA) Tools: The specific versions and configurations of automated QA tools (linters, static analyzers) may require adjustments based on external validation requirements, such as a company's defined Git flow or Continuous Integration (CI) standards. The responsible software engineer must evaluate and tailor the use of these tools to the specific project's needs.

We welcome contributions! If you identify any potential corrections, enhancements, or alternative best practices, we are happy to receive your contributions via Pull Request.


This document was created by Google Gemini.

About

Lab: Cloud Native for Dev Context

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published