Goreen tea : golang boilerplate for data-intensive microservice
Tags: go, microservices, mongodb, opensource
Published: 2021-05-11 07:38:32

---
title: Goreen tea : golang boilerplate for data-intensive microservice
published: true
description: A template project to quickly get you up and running for just about any database-focused application 
tags: 
 - golang 
 - microservice
 - mongodb
 - opensource
cover_image: https://blog.altiano.dev/goreen-tea-introduction/cover.jpeg
---


First of all, I am super thrilled to announce my very first open source project. (#🔥) 
This is just the beginning, and I'm planning to be more involved in 
open source projects at least in the next couple of months.

So, without further ado, 
I introduce you to [**Goreen-tea**](https://gitlab.com/altiano/goreen-tea) 🍵 
A boilerplate project that focused on data-intensive (database heavy) microservice. 
Heavily inspired around the idea of application-centric architecture like [clean architecture](https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html) by Robert Martin.

Clone it and setup a new project:

```bash
git clone https://gitlab.com/altiano/goreen-tea.git --depth 1
cd goreen-tea
bash ./init.sh <base-url> <project-name>
# e.g. bash ./init.sh gitlab.com/altiano awesomeness-api
```

## Goal

My goal is to quickly jump into the project requirements, 
without having to spend much time to setup the same old thing over and over again. 
It is to be more productive.

The boilerplate should be very **simple**, 
packed with some **modern best practices** 
and of course quite **flexible** for changes in the future as new technologies arrived.

## Restaurant order sample

I already set up a sample scenario of kinda like my expectation of being productive of using this project. It is about ordering system in a restaurant.

The requirement are as follow:
* It should be able to record a customer order (CO), which has following specs
  * Who they are (for the sake of simplicity, we'll use the customer email).
  * What they order, at least one.
  * From whom the they heard about the restaurant, we'll use referral code.
  * What will be their own referral code to give to the other.
* It also should be able to assigned the waiter for an order.
  * Depending of how "valuable" the order is and the waiters availability,
    It may be assigned a waiter with higher rating.
* The customer that give their referral code will be notified via email when it is used.
* It would be nice if the restaurant knows the number of customers.

![restaurant order diagram](https://blog.altiano.dev/goreen-tea-introduction/restaurant-order-sample.jpg "restaurant order diagram")

### App package implementation

Here I define that all the above requirements will happen in a one go. 
So we give it a name : `onsiteOrder.go` in the app package.

The four major steps are:

* The creation of CO record **(A)**
* The waiter selection to serve the order **(B)**
* Referral code notification **(C)**
* Live tracking stats **(D)**

I put a label at the end so that we can see the relation of each step with the domain that is responsible for a more detailed implementation.

### Domain package implementation

Then, I define the domain package as below:

* `CustomerOrder`
  * will be responsible to create CO record and generate its own referral code **(A)**
  * notify the referral code owner via email **(C)**
  * notify a customer who will be their waiter **(B)**
* `Waiter`
  * Pick a top waiter currently available **(B)**
  * or to pick a normal waiter **(B)**
  * and able to increase the total serve of a waiter if they are chosen **(B)**
* `AssistanceCordinator`
  A domain doesn't necessarily mean a real business entity.

  There may be times that you need to perform cross-domain calls as a single operation, meaning it would result in an inconsistent state if one call success the the other failed. 
  Think of it kinda like a transaction.

  Here I define an auxiliary domain that responsible for waiter assignment. 
  This domain will depends on the `CustomerOrder` & `Waiter` **(B)**
* `VisitorCounter` (what do think? 🤷‍♂️)

At this point, I highly suggest you to look at the sample code so that it will become clearer.

### Running the project

1. The example use **MongoDB** as its database (I like MongoDB). 
   If you happen to have docker running and haven't install MongoDB yet, 
   you can use the `docker-compose.yaml`.
2. I already setup a sample waiter list, just run `.misc/mongo-playground/seed_waiters.js` in your MongoDB shell.
3. In it, there is also **Jaeger** as the tracing backend but it is optional. 
   If you never used some kind of tracing, I would highly recommended you learn a little bit more about jaeger. 
   Tracing itself is an important part when you project goes live.
4. You should also have `.env` file in the project root directory like this:

```jsx
APP_PORT=8888 # to which port the application will run
MONGO_URI=mongodb://localhost:27017 # your mongodb connection-string
MONGO_DB_NAME=golang-boilerplate # your mongdob collection name
JEAGER_URL=http://localhost:14268/api/traces # Optional if jaeger not present
```

Run it with `go run main.go` ,
Try it with http request like this:

```jsx
POST http://localhost:8888/customerOrder

{
    "Email": "satoshi@domain.com",
    "Orders": ["satay", "fried rice", "meatball", "green tea"],
    "ReferralCode": 0, // indicates satoshi not use any referral code 
}
```

### Core architecture
![goreen tea architecture](https://blog.altiano.dev/goreen-tea-introduction/architecture.jpg "goreen tea architecture")

## A peek at what inside.. 🔭

Some of the features that I haven't mention yet are:

* Unit testing with [go-mock](https://github.com/golang/mock)
* Dependency injection with [google wire](https://github.com/google/wire)
* VS code snippets, tasks and postman-like http testing
* Dockerfile
* K8S manifest
* GitLab CI
* Open telemetry with jaeger
* Rest API with iris

To describe them one by one would be really time consuming. 
And it is not the purpose of this introduction article either. 
See them for yourself, and feel free to ask question to me, directly, anytime. 

## So, looking forward.. 🌄

I'd like to include these features in the next release:

* Data store
  * MongoDB seeding
  * MySQL support
  * Redis
* Servers
  * GRPC
  * GraphQL
* Messaging
  * Kafka
  * NATS

As I said in the beginning, 
this is just the _beginning_, 
I'd love to hear some **feedbacks** to improve this project. 

Thank you for your time.

*Original posted on : https://blog.altiano.dev/goreen-tea-introduction/*