Skip to content

SBTopZZZ-LG/go-dependency-injection

Repository files navigation

Go Todo DI 🚀

This project is a simple To-do application built with Go. While it covers basic features like marking tasks as important, the main goal here is to showcase how to implement Dependency Inversion and Dependency Injection in Go projects. We'll explore both manual methods and popular DI libraries like Uber fx and Google wire.

Table of Contents

Branch Overview

This repository has four branches, each highlighting different approaches to dependency management:

  • without_dep_inv (default): The starting point with basic dependency injection, without dependency inversion.
  • with_dep_inv: Introduces Dependency Inversion to address the initial shortcomings.
  • using_fx: Implements Dependency Injection using the Uber fx library.
  • using_wire: Utilizes Google wire for Dependency Injection.

About the without_dep_inv Branch

This branch represents our initial Go project setup with basic dependency management.

What's Problematic Here?

  1. Tight Coupling Between Repository and Service

    • Why it’s bad: Makes it hard to swap out implementations or reuse components. Testing becomes a headache because dependencies are concrete and not easily mockable.
  2. Tight Coupling Between CLI Commands, Service, and Zap Logger

    • Why it’s bad: Besides design rigidity and testing difficulties, having direct ties to external libraries like Zap means any updates or changes can lead to costly migrations.

Why You Should Care

Without Dependency Inversion and Dependency Injection, your codebase can quickly become rigid and difficult to maintain. It hampers flexibility, modularity, and makes automated testing a nightmare.

Next Steps

Ready to see improvements? Check out the with_dep_inv branch to see how we tackle these issues by introducing Dependency Inversion. From there, you can explore using_fx and using_wire to see how different DI libraries can streamline your project.

Getting Started

Prerequisites

Setting Up the SQL Database

To run the Go Todo DI application, you'll need a MySQL database. Using Docker simplifies the setup process.

Using Docker to Run MySQL

  1. Pull the MySQL Docker Image

    docker pull mysql:latest
  2. Start the MySQL Container

    Replace your_password with a secure password of your choice.

    docker run --name go-todo-mysql -e MYSQL_ROOT_PASSWORD=your_password -e MYSQL_DATABASE=todo_db -p 3306:3306 -d mysql:latest
  3. Verify the MySQL Container is Running

    docker ps | grep go-todo-mysql

    You should see an entry for go-todo-mysql in the list of running containers.

Running the Application

  1. Clone the Repository

    git clone https://github.com/SBTopZZZ-LG/go-dependency-injection.git
  2. Navigate to the Project Directory

    cd go-todo-di
  3. Checkout the without_dep_inv Branch

    git checkout without_dep_inv
  4. Install dependencies

    go mod tidy
  5. Create Application Configuration

    Generate the config.yaml file with the necessary configurations:

    cat <<'EOF' > config.yaml
    logger:
      level: "info"
      development: true
      encoding: "json"
      output_paths:
        - "./logs/all-logs.log"
      error_output_paths:
        - "./logs/errors.log"
      encoder_config:
        line_ending: "\n"
    
    database:
      driver: "mysql"
      user: "root"
      password: "your_password"
      host: "localhost"
      port: 3306
      name: "todo_db"
      params: "parseTime=true"
    EOF

    Note: Replace your_password with the password you set for the MySQL root user.

  6. Create Logs Directory

    To prevent the application from crashing due to missing log directories, create the logs folder:

    mkdir logs
  7. Run the Application

    go run main.go

    The application should now be running, and you can interact with the CLI to manage your To-dos.

Usage

Interact with the Go Todo DI application using the following commands. Each command allows you to manage your to-dos effectively through the CLI.

go run main.go <command> [{<id>|<content>|<id> <content>}]

Create a To-do

Syntax

go run main.go create_todo <message>

Example

go run main.go create_todo "Write a Blog"

List To-dos

Syntax

go run main.go list_todos

Get a To-do by ID

Retrieve a specific to-do using its unique ID.

Syntax

go run main.go get_todo <id>

Example

go run main.go get_todo 1

Update a To-do

Syntax

go run main.go update_todo <id> <new_message>

Example

go run main.go update_todo 1 "Buy groceries and cook dinner"

Delete a To-do

Syntax

go run main.go delete_todo <id>

Example

go run main.go delete_todo 1

Mark a To-do as Important

Flag a to-do as important to prioritize it.

Syntax

go run main.go make_todo_important <id>

Example

go run main.go make_todo_important 1

Mark a To-do as Not Important

Remove the important flag from a to-do.

Syntax

go run main.go make_todo_not_important <id>

Example

go run main.go make_todo_not_important 1

About

A Go To-do app showcasing Dependency Inversion and Injection patterns (Manual, Uber fx, Google wire).

Topics

Resources

Stars

Watchers

Forks

Contributors

Languages