How to Build Your Own TODO-list Service With Golang and MongoDB

Many have wondered how a simple task sheet or applications that provide such functionality work. In this article, we will write a small TODO service.


This content originally appeared on HackerNoon and was authored by Ilia Ivankin

Many have wondered how a simple task sheet or applications that provide such functionality work. In this article, I invite you to consider how you can write your small service in Go in a couple of hours and put everything in a database.


Why Goalng?

The Keys are Simplicity and Efficiency.

  • Minimalistic Design: Easy to learn and use, focusing on simplicity.

\

  • Fast Compilation: Compiled to native code, ensuring speedy execution and deployment.

\

  • Concurrency Goroutines: Lightweight threads managed by Go runtime make concurrent programming more superficial and efficient. Channels: Facilitate safe communication between goroutines, avoiding the pitfalls of shared memory. Robust Standard Library.

\

  • Rich Ecosystem: Extensive standard library covering web servers, cryptography, I/O, and more.

\

  • Cross-Platform: Compiles to various operating systems and architectures without modification.

Let's Check the Trends:

The Rise of Cloud-Native Development and Microservices

  • ==Docker== allows developers to package applications into containers, ensuring consistency across different environments. For example, a web server can be run in a Docker container to ensure it behaves similarly in development and production. Consul Consul provides service discovery and configuration management.

\

  • ==K8s== (Kubernetes) - automates the deployment, scaling, and management of containerized applications.

\

  • ==gRPC== is a high-performance, open-source universal RPC framework. Example: Using gRPC to enable efficient communication between microservices written in different languages.

\

  • ==Terraform== is used to safely and efficiently build, change, and version infrastructure. An example is using Terraform scripts to provision cloud infrastructure on AWS.

Golang and the Internet of Things (IoT)

  • ==NATS== is a simple, high-performance, open-source messaging system for cloud-native applications, IoT messaging, and microservices architectures.

\

  • ==InfluxData== is a platform for handling time series data, which is essential for IoT applications.

Growing Adoption of Machine Learning and Artificial Intelligence (AI)

  • ==“TensorFlow Go”== provides machine learning tools that can be used with Go.

\

  • ==Gorgonia== is a library that brings machine-learning capabilities to Go.

\

  • ==GoLearn== is a machine-learning library for Go.

The Expanding Golang Ecosystem

  • ==Gin== is a high-performance HTTP web framework written in Golang.

\

  • ==Viper== is a complete configuration solution for Go applications. For example, It Manages application configuration using Viper to support formats like JSON, YAML, and TOML.

\

  • ==Cobra== is a library that creates powerful modern CLI applications.

\

  • ==GORM== is an ORM library for Golang.

\

  • ==Protocol Buffers (Protobuf)== is a method developed by Google for serializing structured data.

Why MongoDB?

We need to collect data for our tasks and be flexible. We don't need to create a schema or relationship between something.

\ What can we have using it:

  • Flexible Schema: MongoDB allows for schema-less design, making it easy to handle unstructured or semi-structured data.

\

  • Scalability: It supports horizontal scaling, allowing you to distribute data across multiple servers.

\

  • Rich Query Language: MongoDB provides a powerful query language, including support for complex queries, indexing, and aggregation.

    \ That’s nice for our example:

  {
  "_id": "66532b210d9944a92a88ef4b",
  "title": "Go to the groceries",
  "description": "Purchase milk, eggs, and bread",
  "completed": false
  }

\ A local run with docker:

version: '3.1'

services:

mongo:
  image: mongo
  ports:
    - "27017:27017"
  environment:
    MONGO_INITDB_ROOT_USERNAME: root
    MONGO_INITDB_ROOT_PASSWORD: example

\ Now, we have DB, but we need to work with it as well.

Compass

MongoDB Compass is a graphical user interface (GUI) for MongoDB designed to facilitate developers, database administrators, and data analysts' interactions with their MongoDB databases. It provides a user-friendly visual representation of the data and powerful tools for querying, managing, and optimizing databases.

\ ==Download it here: https://www.mongodb.com/products/tools/compass.==

\ Why MongoDB Compass is Easy to Use:

  • Graphical Interface: The graphical interface reduces the learning curve associated with using MongoDB, making it accessible to users with varying technical expertise.

\

  • Drag-and-Drop Functionality: Many features, such as query building and schema design, use drag-and-drop functionality, simplifying complex operations and making them more intuitive.

\

  • Real-Time Feedback: Compass provides real-time feedback as you interact with your data, allowing you to see the results of your queries and modifications immediately.

\

  • Comprehensive Documentation and Support: MongoDB Compass is backed by extensive documentation and a supportive community. Users can easily find tutorials, guides, and forums to help them navigate any challenges.

\


Fast Installations Before We Start

Install VS code (It's free).

Visit https://code.visualstudio.com/.

\ Installing Go Visit golang.org to download the installer for your operating system.

\ Follow the installation instructions provided on the website.

\ Verify the installation by opening a terminal/command prompt and typing:

go version

\ And then add the Golang extension:

package main

import "fmt"

func main() {
  fmt.Println("Hello, World!")
}

\ And run it:

go run main.go

System Design (Small, But Still ;D)

The document should have:

Title
Description
Status

\ Our previous JSON file as a reference: JSON

{
"_id": "66532b210d9944a92a88ef4b",
"title": "Go to the groceries",
"description": "Purchase milk, eggs, and bread",
"completed": false
}

\ Next step: Create main methods such as CRUD.

\ Create -The Create operation involves adding new records to a database. This is the initial step in data management, where new data entries are inserted into the database.

\ Read - The Read operation retrieves data from the database. It allows users to fetch and display data without modifying it.

\ Update - The Update operation involves modifying existing records in the database. It changes the data within a record while maintaining its identity.

\ Delete—The Delete operation permanently removes records from a database. It is often accompanied by a confirmation step to prevent accidental deletions.

\ We are going to implement only the “CREATE” or add method because I’d like to share a good example. After that, you can implement others.

\ Project structure:

todo-list/
│
├── cmd/
│   └── main.go
├── pkg/
│   └── handler
│      └── add_task.go
│      └── http_handler.go
│   └── mapper
│       └── task.go
│   └── model
│        └── task.go
│   └── usecase
│        └── task
│           └── repository
│               └── add_task.go
│               └── mongo_repositiry.go
│               └── repository.go
│           └── service
│               └── add_task.go
│               └── service.go
└── go.mod

I want to use the way to separate all responsibilities by folders.

  • Handler - HTTP layer
  • Model - structures for data
  • Use cases - business layers with service and repository.

\ Let's start with a data structure for our app:

package model

import "go.mongodb.org/mongo-driver/bson/primitive"

type Task struct {
  ID         string json:"id"
  Title      string json:"title"
  Desciption string json:"description"
  Completed  bool   json:"completed"
}

type MongoTask struct {
  ID         primitive.ObjectID json:"id" bson:"_id"
  Title      string             json:"title"
  Desciption string             json:"description"
  Completed  bool               json:"completed"
}

Task - for HTTP request, MongoTask - for MongoDb layer. Using two structures is easy because sometimes we don't need to send additional data to our users. For example, we might have a secret field, like a username, which we must hide. Now that we know CRUD, let's code it!

\ Repository layer:

type Repository interface {
  AddTask(ctx context.Context, task model.MongoTask) error
}

\ Service layer:

 type TodoService interface { 
  AddTask(ctx context.Context, task model.Task) error  
}

\ Let's connect and inject dependencies:

// Initialize repository, service, and handler
todoRepo := repository.NewMongoRepository(client)
todoService := service.NewService(todoRepo)
todoHandler := handler.NewHandler(todoService)

\ Finally, context and connections:

func main() {
  ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
  defer cancel()

  // Set MongoDB client options
  clientOptions := options.Client().ApplyURI("mongodb://localhost:27017").SetAuth(options.Credential{
    Username: "root",
    Password: "example",
  })

  client, err := mongo.Connect(ctx, clientOptions)
  if err != nil {
    log.Fatal(err)
  }

  err = client.Ping(ctx, nil)
  if err != nil {
    log.Fatal(err)
  }

  log.Println("Connected to MongoDB!")

  // Initialize repository, service, and handler
  todoRepo := repository.NewMongoRepository(client)
  todoService := service.NewService(todoRepo)
  todoHandler := handler.NewHandler(todoService)

  // Set up routes
  http.HandleFunc("/api/v1/add", todoHandler.AddTask)

  // Create a server
  srv := &http.Server{
    Addr:    ":8080",
    Handler: nil,
  }
  // .. todo
}

Demo

Now, we have everything, and we can start to analyze what happens when we call our service.

curl -X POST http://localhost:8080/add

#-H "Content-Type: application/json"
#-d '{
"id": 1,
"title": "Buy groceries",
"completed": false
#}'

POST http://localhost:8080/api/v1/add
Content-Type: application/json

{
  "title": "Add description to the structure",
  "description": "your desc here..."
}

\ We will process the request using the handler layer, decode it using JSON lib, and send the model to the service layer.

func (h *Handler) AddTask(w http.ResponseWriter, r *http.Request) {
  ctx := context.Background()
  var task model.Task
  err := json.NewDecoder(r.Body).Decode(&task)
  if err != nil {
    http.Error(w, "Invalid request body", http.StatusBadRequest)
    return
  }

  err = h.Service.AddTask(ctx, task)
  if err != nil {
    http.Error(w, err.Error(), http.StatusInternalServerError)
    return
  }

  w.WriteHeader(http.StatusCreated)
}

\ Next step, process it in the service layer: (just proxy and convert the model to DTO or Entity for MongoDb).

func (s *Service) AddTask(ctx context.Context, task model.Task) error {
  return s.Repo.AddTask(ctx, mapper.MapToDto(task))
}

\ Lastly, use the MongoDB client, and save the task to DB.

func (r *MongoRepository) AddTask(ctx context.Context, task model.MongoTask) error {
  task.ID = primitive.NewObjectID()

  _, err := r.collection.InsertOne(ctx, task) 

  return err
}

\ That's it! We finished the first method for saving the task. You can implement three more methods, or you can check them out here: Golang Workshop.


Conclusion

In conclusion, we've created a small yet robust task management service using Golang and MongoDB. This exercise demonstrated how Golang's simplicity, concurrency features, and MongoDB's flexibility and scalability provide a powerful platform for building modern web applications.

\ With the right tools and architecture, you can efficiently manage and manipulate data, creating scalable and maintainable services.

\ Now, we know how to build our to-do list and understand that it’s not hard to code.

\ Take care!


This content originally appeared on HackerNoon and was authored by Ilia Ivankin


Print Share Comment Cite Upload Translate Updates
APA

Ilia Ivankin | Sciencx (2024-07-23T00:48:14+00:00) How to Build Your Own TODO-list Service With Golang and MongoDB. Retrieved from https://www.scien.cx/2024/07/23/how-to-build-your-own-todo-list-service-with-golang-and-mongodb/

MLA
" » How to Build Your Own TODO-list Service With Golang and MongoDB." Ilia Ivankin | Sciencx - Tuesday July 23, 2024, https://www.scien.cx/2024/07/23/how-to-build-your-own-todo-list-service-with-golang-and-mongodb/
HARVARD
Ilia Ivankin | Sciencx Tuesday July 23, 2024 » How to Build Your Own TODO-list Service With Golang and MongoDB., viewed ,<https://www.scien.cx/2024/07/23/how-to-build-your-own-todo-list-service-with-golang-and-mongodb/>
VANCOUVER
Ilia Ivankin | Sciencx - » How to Build Your Own TODO-list Service With Golang and MongoDB. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2024/07/23/how-to-build-your-own-todo-list-service-with-golang-and-mongodb/
CHICAGO
" » How to Build Your Own TODO-list Service With Golang and MongoDB." Ilia Ivankin | Sciencx - Accessed . https://www.scien.cx/2024/07/23/how-to-build-your-own-todo-list-service-with-golang-and-mongodb/
IEEE
" » How to Build Your Own TODO-list Service With Golang and MongoDB." Ilia Ivankin | Sciencx [Online]. Available: https://www.scien.cx/2024/07/23/how-to-build-your-own-todo-list-service-with-golang-and-mongodb/. [Accessed: ]
rf:citation
» How to Build Your Own TODO-list Service With Golang and MongoDB | Ilia Ivankin | Sciencx | https://www.scien.cx/2024/07/23/how-to-build-your-own-todo-list-service-with-golang-and-mongodb/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.