/products-api

Products RESTful API

Primary LanguageGo

Products RESTful API - Coding evaluation

REST API for product storage management

Quick Links
How to run (Golang)
# Load required environment variables
export $(grep -v ^# .env.example)
# Run SQL migrations
go run ./cmd/migrations/migrations.go
# Run HTTP server
go run ./cmd/server/server.go
Unit tests

Structure

package foo

import (
	"strconv"
	"testing"
)

func TestX(t *testing.T) {
	// Table Driven Testing 
	tdt := []struct{}{
	    {},	// Test Case
    }
	
	// Setup
	x := struct{}{}
	
	// Cleanup function (Optional)
	t.Cleanup(func() {})
	
	// Subtests 
	for i, v := range tdt {
		t.Run(strconv.Itoa(i), func(t *testing.T){
			t.Log(x, v)
			// Cleanup function for each subtest (Optional)
			t.Cleanup(func() {})
		})
	}
}

Notes

  • Added custom cli flags to modify unit test behavior (for example, if the -V flag is used when running unit tests, additional logs are displayed)
Architecture style explained

The architecture pattern used in this project is the most common form of layered architecture pattern with three layers (presentation, business, and data access) and some additional changes about communication between layers, due to architecture decisions (explained below πŸ‘‡πŸΌ)

β”œβ”€β”€ cmd            πŸ‘‰πŸΌ (executable commands)
└── internal
    β”œβ”€β”€ business   πŸ‘‰πŸΌ (business logic layer)
    β”œβ”€β”€ dependency πŸ‘‰πŸΌ (manage dependencies)
    β”œβ”€β”€ handler    πŸ‘‰πŸΌ (presentation layer)
    β”œβ”€β”€ model      πŸ‘‰πŸΌ (data transfer objects, business objects and enums)
    └── repository πŸ‘‰πŸΌ (data access layer)

See more about layer architecture pattern

Communication between layers

πŸ’₯IMPORTANTπŸ’₯ The layers are integrated in a top-down communication model: each layer can hold dependency only on the layer directly beneath it.


One way to communicate the layers to share data between it is to use Domain Objects to communicate the Presentation Layer with the Business Layer and Data Transfer Objects to communicate the Business Layer with the Access Data Layer

     
    |--------------------|                      |----------------------|                             |-------------------|
    | Presentation layer | ==[domain object]==> | Business logic layer | ==[data transfer object]==> | Data access layer |
    |--------------------|                      |----------------------|                             |-------------------|

However, many times data transfer objects and domain objects are similar or identical, which lead to redundancy... To solve this problem I decided create the model package to be the way in that the three layers can be shared information using data types in common.

     
    |--------------------|           |----------------------|           |-------------------|
    | Presentation layer | ========> | Business logic layer | ========> | Data access layer |
    |--------------------|           |----------------------|           |-------------------|
              ^                                 ^                                 ^
              |                                 |                                 |
              |=================================|=================================|
                                                |
                                     |----------------------|
                                     |     Package model    |
                                     |----------------------|