Understanding Microservices: A Beginner's Guide for Developers 👨‍💻
Tags: microservices, go, developers, programming
Published: 2023-01-26 16:00:21

Ever had a feeling of being an impostor? If yes, then you're not alone.
My journey as a developer majoring on  back-end development has been a roller-coaster ride. 
There have been times when I assumed I was not making any progress. 
A quote by Dan John: _"If it is important, do it everyday. If it's not important, don't do it at all."_
I apply this principle to programming and it's been helping.

The concept of Microservices, can be applied to learning software development. It's majorly about building and deploying software applications as a collection of small, independent services, rather than a monolithic application.

It's easy to get overwhelmed by different technologies that are used and trying to learn all at once. Invariably that method does not help build a strong foundation. 
I have come to understand that starting with the basics and gradually picking up later adds up to becoming well versed in the field.

So in this post, we will be looking at Microservices in Software development.

#What are Microservices?

A Microservice is a small, independent service that performs a specific function in an application. Each service runs its own process and communicates with other services through a lightweight mechanism such as an API. The services can be written in different programming languages and can be deployed on different servers. This allows for flexibility and scalability in the development process.

##Leads of Microservices:

1. Technology diversity: Microservices can be developed in different languages and technologies, making it possible to use the best tool for the job.

2. Scalability: Each service can be scaled independently, which aid the process of handling high traffic or implementing new features.

3. Resilience: When using microservices, if one service fails, the others can continue to function, making the overall application more resilient.

4. Flexibility: Services can be developed and deployed independently, allowing for faster development and deployment cycles.

##An Overview of How to Implement Microservices:

1. Identify the services: Break down the application into smaller services that perform specific functions.

2. Define the communication mechanism: Decide on a lightweight mechanism for communication between services, such as an API.

3. Develop and deploy the services: Develop and deploy each service independently

4. Test and Monitor: Test and monitor each service to ensure they are working correctly and to identify potential issues.

###Here's an example of how to implement a simple Microservice architecture using Go and HTTP:

A Microservice architecture for a simple E-commerce application 

Let's say we're building an e-commerce app that has a catalog service, an order service, and a payment service. Each service will run on it's own endpoint and communicate with each other through HTTP requests.

First, let's create a simple catalog service that returns a list of products in JSON format: 

```go
package main

import (
	"encoding/json"
	"fmt"
	"net/http"
)

type Product struct {
	ID		int			`json:"id"`
	Name	string	`json:"name"`
	Price	int			`json:"price"`
}

var products = []Product{
	{ID: 1, Name: "Product 1", Price: 100},
	{ID: 2, Name: "Product 2", Price: 200},
	{ID: 3, Name:	"Product 3", Price: 300},
}

func main() {
	http.HandleFunc("/products", func(w http.ResponseWriter, r *http.Request) {
		json.NewEncoder(w).Encode(products)
	})

	fmt.Println("Starting server on port 8000")
	http.ListenAndServe(":8000", nil)
}
```

This service runs on the endpoint `/products` and returns a JSON object containing a list of products.

Next, let's create an order service that takes a product ID and creates an order:

```go
package main

import (
	"encoding/json"
	"fmt"
	"net/http"
)

type Order struct {
	ID					int			`json:"id"`
	ProductID		int			`json:"product_id"`
	CustomerID	int			`json:"customer_id"`
	Status			string	`json:"status"`
}

var orderID = 1

var orders = []Order{}

func main() {
	http.HandleFunc("/order", func(w http.ResponseWriter, r *http.Request) {
		if r.Method == "POST" {
			var order Order
			json.NewDecoder(r.Body).Decode(&order)
			order.ID = orderID
			orderID++
			orders = append(orders, order)
			json.NewEncoder(w).Encode(order)
		} else {
			json.NewEncoder(w).Encode(orders)
		}
	})

	fmt.Println("Starting server on port 8001")
	http.ListenAndServe(":8001", nil)
}
```

This service runs on the endpoint '/order' and accepts POST requests with a JSON object containing a product ID and customer ID. It then creates an order and returns the order information in JSON format.

Finally, we will create a payment service that takes an order ID and processes a payment:

```go
package main

import (
	"encoding/json"
	"fmt"
	"net/http"
)

type Payment struct{
	ID				int			`json:"id"`
	OrderID		int			`json:"order_id"`
	Amount		int			`json:"amount"`
	Status		string	`json:"status"`
}

var paymentID = 1

var payments = []Payment{}

func main() {
	http.HandleFunc("/payment", func(w http.ResponseWriter, r *http.Request) {
		if r.Method == "POST" {
			var payment Payment
			json.NewDecoder(r.Body).Decode(&payment)
			payment.ID = paymentID
			paymentID++
			payment.Status = "success"
			payments = append(payments, payment)
			json.NewEncoder(w).Encode(payment)
		} else {
			json.NewEncoder(w).Encode(payments)
		}
	})

	// displays the server starting

	fmt.Println("Starting server on port 8002")
	http.ListenAndServe(":8002", nil)
}
```

This service runs on the endpoint `/payment` and accepts POST requests with a JSON object containing an order ID and amount. It then processes a payment and returns the payment information in JSON format, including the status of payment.

From our example, we can see that the catalog service, order service, and payment service are all running independently on their own endpoints and communicating with each other through HTTP requests. This allows for flexibility in development and deployment, and makes it easy to scale and test each service individually.

Real-world microservices architectures are more complex than this example and will require best practices such as service discovery, load balancing, and security.
With proper planning and implementation, Microservices can be a great choice for your next project.

Till next time.

⚡codeDaily