Skip to content

Commit 2ab9549

Browse files
enhancement this repository
1 parent 5ae1831 commit 2ab9549

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+2358
-1243
lines changed

.coverage/.keep

Whitespace-only changes.

.gitignore

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1-
config/config-local.yaml
1+
vendor/
22

3-
vendor/
3+
# we want to ignore files under this directory (ends with /*)
4+
.coverage/*
5+
6+
# we want to keep track of this .keep files (starts with !)
7+
!.keep

cmd/api/main.go

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,53 @@ package main
22

33
import (
44
"context"
5-
"os"
5+
"time"
66

77
"github.com/DoWithLogic/golang-clean-architecture/config"
88
"github.com/DoWithLogic/golang-clean-architecture/internal/app"
9+
"github.com/DoWithLogic/golang-clean-architecture/pkg/observability"
10+
"github.com/labstack/gommon/log"
911
)
1012

1113
func main() {
12-
env := os.Getenv("env")
13-
if env == "" {
14-
env = "local"
14+
// Load the application configuration from the specified directory.
15+
cfg, err := config.LoadConfig("config")
16+
if err != nil {
17+
// If an error occurs while loading the configuration, panic with the error.
18+
panic(err)
1519
}
1620

17-
cfg, err := config.LoadConfig(env)
21+
// Set the time zone to the specified value from the configuration.
22+
_, err = time.LoadLocation(cfg.Server.TimeZone)
1823
if err != nil {
19-
panic(err)
24+
// If an error occurs while setting the time zone, log the error and exit the function.
25+
log.Error("Error on setting the time zone: ", err)
26+
return
27+
}
28+
29+
// Initialize observability components if observability is enabled in the configuration.
30+
if cfg.Observability.Enable {
31+
// Initialize the tracer provider for distributed tracing.
32+
tracer, err := observability.InitTracerProvider(cfg)
33+
if err != nil {
34+
log.Warn("Failed to initialize tracer: ", err)
35+
}
36+
37+
// Initialize the meter provider for metrics collection.
38+
meter, err := observability.InitMeterProvider(cfg)
39+
if err != nil {
40+
log.Warn("Failed to initialize meter: ", err)
41+
}
42+
43+
// Ensure that the tracer and meter are shut down when the main function exits.
44+
defer func() {
45+
if tracer != nil {
46+
tracer.Shutdown(context.Background())
47+
}
48+
if meter != nil {
49+
meter.Shutdown(context.Background())
50+
}
51+
}()
2052
}
2153

2254
app.NewApp(context.Background(), cfg).Run()

config/config-local.yaml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
App:
2+
Name: "golang-clean-architecture"
3+
Version: "v0.0.1"
4+
Scheme: "http"
5+
Host: "localhost:3002"
6+
Environment: local #local,development,staging,production
7+
8+
Server:
9+
Port: "9090"
10+
Debug: true
11+
TimeZone: "Asia/Jakarta"
12+
13+
14+
Database:
15+
Host: 127.0.0.1
16+
Port: 3306
17+
Name: users
18+
User: root
19+
Password: pwd
20+
21+
Authentication:
22+
Key: DoWithLogic!@#
23+
24+
Observability:
25+
Enable: false
26+
Mode: "otlp/http"

config/config-local.yaml.example

Lines changed: 0 additions & 21 deletions
This file was deleted.

config/config.go

Lines changed: 80 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,41 @@
11
package config
22

33
import (
4+
"errors"
45
"fmt"
5-
"time"
6+
"log"
7+
"strings"
68

79
"github.com/spf13/viper"
810
)
911

1012
type (
1113
Config struct {
12-
Database DatabaseConfig
14+
App AppConfig
1315
Server ServerConfig
16+
Database DatabaseConfig
1417
Authentication AuthenticationConfig
18+
Observability ObservabilityConfig
19+
JWT JWTConfig
20+
}
21+
22+
// AppConfig holds the configuration related to the application settings.
23+
AppConfig struct {
24+
Name string
25+
Version string
26+
Schema string
27+
Host string
28+
Environment string
29+
}
30+
31+
// ServerConfig holds the configuration for the server settings.
32+
ServerConfig struct {
33+
Port string // The port on which the server will listen.
34+
Debug bool // Indicates if debug mode is enabled.
35+
TimeZone string // The time zone setting for the server.
1536
}
1637

38+
// DatabaseConfig holds the configuration for the database connection.
1739
DatabaseConfig struct {
1840
Host string
1941
Port int
@@ -22,37 +44,76 @@ type (
2244
Password string
2345
}
2446

25-
ServerConfig struct {
26-
Name string
27-
Version string
28-
RPCPort string
29-
RESTPort string
30-
Debug bool
31-
Environment string
32-
ReadTimeout time.Duration
33-
WriteTimeout time.Duration
47+
AuthenticationConfig struct {
48+
Key string
3449
}
3550

36-
AuthenticationConfig struct {
37-
Key string
38-
SecretKey string
39-
SaltKey string
51+
// ObservabilityConfig holds the configuration for observability settings.
52+
ObservabilityConfig struct {
53+
Enable bool // Indicates if observability is enabled.
54+
Mode string // Specifies the observability mode.
55+
}
56+
57+
JWTConfig struct {
58+
Key string
59+
Expired int
60+
Label string
4061
}
4162
)
4263

43-
func LoadConfig(env string) (Config, error) {
44-
viper.SetConfigFile(fmt.Sprintf("config/config-%s.yaml", env))
64+
// LoadConfig loads the configuration from the specified filename.
65+
func LoadConfig(filename string) (Config, error) {
66+
// Create a new Viper instance.
67+
v := viper.New()
4568

46-
if err := viper.ReadInConfig(); err != nil {
69+
// Set the configuration file name, path, and environment variable settings.
70+
v.SetConfigName(fmt.Sprintf("config/%s", filename))
71+
v.AddConfigPath(".")
72+
v.AutomaticEnv()
73+
v.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
74+
75+
// Read the configuration file.
76+
if err := v.ReadInConfig(); err != nil {
4777
fmt.Printf("Error reading config file: %v\n", err)
4878
return Config{}, err
4979
}
5080

81+
// Unmarshal the configuration into the Config struct.
5182
var config Config
52-
if err := viper.Unmarshal(&config); err != nil {
83+
if err := v.Unmarshal(&config); err != nil {
5384
fmt.Printf("Error unmarshaling config: %v\n", err)
5485
return Config{}, err
5586
}
5687

5788
return config, nil
5889
}
90+
91+
// LoadConfigPath loads the configuration from the specified path.
92+
func LoadConfigPath(path string) (Config, error) {
93+
// Create a new Viper instance.
94+
v := viper.New()
95+
96+
// Set the configuration file name, path, and environment variable settings.
97+
v.SetConfigName(path)
98+
v.AddConfigPath(".")
99+
v.AutomaticEnv()
100+
v.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
101+
102+
// Read the configuration file.
103+
if err := v.ReadInConfig(); err != nil {
104+
// Handle the case where the configuration file is not found.
105+
if _, ok := err.(viper.ConfigFileNotFoundError); ok {
106+
return Config{}, errors.New("config file not found")
107+
}
108+
return Config{}, err
109+
}
110+
111+
// Parse the configuration into the Config struct.
112+
var c Config
113+
if err := v.Unmarshal(&c); err != nil {
114+
log.Printf("unable to decode into struct, %v", err)
115+
return Config{}, err
116+
}
117+
118+
return c, nil
119+
}

config/config.yaml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
App:
2+
Name: "golang-clean-architecture"
3+
Version: "v0.0.1"
4+
Scheme: "http"
5+
Host: "localhost:3002"
6+
Environment: local #local,development,staging,production
7+
8+
Server:
9+
Port: "9090"
10+
Debug: true
11+
TimeZone: "Asia/Jakarta"
12+
13+
14+
Database:
15+
Host: 127.0.0.1
16+
Port: 3306
17+
Name: users
18+
User: root
19+
Password: pwd
20+
21+
Authentication:
22+
Key: DoWithLogic!@#
23+
24+
Observability:
25+
Enable: false
26+
Mode: "otlp/http"

database/mysql/migration/20230924142159_add_user_table.sql

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,7 @@ CREATE TABLE `users` (
99
`user_type` varchar(50) NOT NULL,
1010
`is_active` tinyint(1) NOT NULL,
1111
`created_at` timestamp NOT NULL,
12-
`created_by` varchar(255) NOT NULL,
1312
`updated_at` timestamp DEFAULT NULL,
14-
`updated_by` varchar(255) DEFAULT NULL,
1513
PRIMARY KEY (`id`)
1614
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
1715

docker-compose.yml

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,7 @@ services:
1717
interval: 0.5s
1818
timeout: 10s
1919
retries: 10
20-
golang-clean-architecture:
21-
build:
22-
context: .
23-
dockerfile: Dockerfile # Specify the path to your Dockerfile
24-
ports:
25-
- 8080:8080
26-
- 9090:9090
27-
volumes:
28-
- ./config/config-local.yaml:/app/config/config-local.yaml
29-
depends_on:
30-
- mysql-db
20+
entrypoint:
21+
sh -c "
22+
echo 'CREATE DATABASE IF NOT EXISTS users;' > /docker-entrypoint-initdb.d/init.sql;
23+
/usr/local/bin/docker-entrypoint.sh --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci"

0 commit comments

Comments
 (0)