feat: basic config, logger, main loop
This commit is contained in:
141
backend/.gitignore
vendored
141
backend/.gitignore
vendored
@@ -1,5 +1,8 @@
|
|||||||
# Created by https://www.toptal.com/developers/gitignore/api/go,goland,visualstudiocode,vim
|
# Created by https://www.toptal.com/developers/gitignore/api/vim,dotenv,go
|
||||||
# Edit at https://www.toptal.com/developers/gitignore?templates=go,goland,visualstudiocode,vim
|
# Edit at https://www.toptal.com/developers/gitignore?templates=vim,dotenv,go
|
||||||
|
|
||||||
|
### dotenv ###
|
||||||
|
.env
|
||||||
|
|
||||||
### Go ###
|
### Go ###
|
||||||
# If you prefer the allow list template instead of the deny list, see community template:
|
# If you prefer the allow list template instead of the deny list, see community template:
|
||||||
@@ -24,119 +27,6 @@
|
|||||||
# Go workspace file
|
# Go workspace file
|
||||||
go.work
|
go.work
|
||||||
|
|
||||||
### GoLand ###
|
|
||||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
|
|
||||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
|
||||||
|
|
||||||
# User-specific stuff
|
|
||||||
.idea/**/workspace.xml
|
|
||||||
.idea/**/tasks.xml
|
|
||||||
.idea/**/usage.statistics.xml
|
|
||||||
.idea/**/dictionaries
|
|
||||||
.idea/**/shelf
|
|
||||||
|
|
||||||
# AWS User-specific
|
|
||||||
.idea/**/aws.xml
|
|
||||||
|
|
||||||
# Generated files
|
|
||||||
.idea/**/contentModel.xml
|
|
||||||
|
|
||||||
# Sensitive or high-churn files
|
|
||||||
.idea/**/dataSources/
|
|
||||||
.idea/**/dataSources.ids
|
|
||||||
.idea/**/dataSources.local.xml
|
|
||||||
.idea/**/sqlDataSources.xml
|
|
||||||
.idea/**/dynamic.xml
|
|
||||||
.idea/**/uiDesigner.xml
|
|
||||||
.idea/**/dbnavigator.xml
|
|
||||||
|
|
||||||
# Gradle
|
|
||||||
.idea/**/gradle.xml
|
|
||||||
.idea/**/libraries
|
|
||||||
|
|
||||||
# Gradle and Maven with auto-import
|
|
||||||
# When using Gradle or Maven with auto-import, you should exclude module files,
|
|
||||||
# since they will be recreated, and may cause churn. Uncomment if using
|
|
||||||
# auto-import.
|
|
||||||
# .idea/artifacts
|
|
||||||
# .idea/compiler.xml
|
|
||||||
# .idea/jarRepositories.xml
|
|
||||||
# .idea/modules.xml
|
|
||||||
# .idea/*.iml
|
|
||||||
# .idea/modules
|
|
||||||
# *.iml
|
|
||||||
# *.ipr
|
|
||||||
|
|
||||||
# CMake
|
|
||||||
cmake-build-*/
|
|
||||||
|
|
||||||
# Mongo Explorer plugin
|
|
||||||
.idea/**/mongoSettings.xml
|
|
||||||
|
|
||||||
# File-based project format
|
|
||||||
*.iws
|
|
||||||
|
|
||||||
# IntelliJ
|
|
||||||
out/
|
|
||||||
|
|
||||||
# mpeltonen/sbt-idea plugin
|
|
||||||
.idea_modules/
|
|
||||||
|
|
||||||
# JIRA plugin
|
|
||||||
atlassian-ide-plugin.xml
|
|
||||||
|
|
||||||
# Cursive Clojure plugin
|
|
||||||
.idea/replstate.xml
|
|
||||||
|
|
||||||
# SonarLint plugin
|
|
||||||
.idea/sonarlint/
|
|
||||||
|
|
||||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
|
||||||
com_crashlytics_export_strings.xml
|
|
||||||
crashlytics.properties
|
|
||||||
crashlytics-build.properties
|
|
||||||
fabric.properties
|
|
||||||
|
|
||||||
# Editor-based Rest Client
|
|
||||||
.idea/httpRequests
|
|
||||||
|
|
||||||
# Android studio 3.1+ serialized cache file
|
|
||||||
.idea/caches/build_file_checksums.ser
|
|
||||||
|
|
||||||
### GoLand Patch ###
|
|
||||||
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
|
|
||||||
|
|
||||||
# *.iml
|
|
||||||
# modules.xml
|
|
||||||
# .idea/misc.xml
|
|
||||||
# *.ipr
|
|
||||||
|
|
||||||
# Sonarlint plugin
|
|
||||||
# https://plugins.jetbrains.com/plugin/7973-sonarlint
|
|
||||||
.idea/**/sonarlint/
|
|
||||||
|
|
||||||
# SonarQube Plugin
|
|
||||||
# https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin
|
|
||||||
.idea/**/sonarIssues.xml
|
|
||||||
|
|
||||||
# Markdown Navigator plugin
|
|
||||||
# https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced
|
|
||||||
.idea/**/markdown-navigator.xml
|
|
||||||
.idea/**/markdown-navigator-enh.xml
|
|
||||||
.idea/**/markdown-navigator/
|
|
||||||
|
|
||||||
# Cache file creation bug
|
|
||||||
# See https://youtrack.jetbrains.com/issue/JBR-2257
|
|
||||||
.idea/$CACHE_FILE$
|
|
||||||
|
|
||||||
# CodeStream plugin
|
|
||||||
# https://plugins.jetbrains.com/plugin/12206-codestream
|
|
||||||
.idea/codestream.xml
|
|
||||||
|
|
||||||
# Azure Toolkit for IntelliJ plugin
|
|
||||||
# https://plugins.jetbrains.com/plugin/8053-azure-toolkit-for-intellij
|
|
||||||
.idea/**/azureSettings.xml
|
|
||||||
|
|
||||||
### Vim ###
|
### Vim ###
|
||||||
# Swap
|
# Swap
|
||||||
[._]*.s[a-v][a-z]
|
[._]*.s[a-v][a-z]
|
||||||
@@ -158,24 +48,5 @@ tags
|
|||||||
# Persistent undo
|
# Persistent undo
|
||||||
[._]*.un~
|
[._]*.un~
|
||||||
|
|
||||||
### VisualStudioCode ###
|
# End of https://www.toptal.com/developers/gitignore/api/vim,dotenv,go
|
||||||
.vscode/*
|
|
||||||
!.vscode/settings.json
|
|
||||||
!.vscode/tasks.json
|
|
||||||
!.vscode/launch.json
|
|
||||||
!.vscode/extensions.json
|
|
||||||
!.vscode/*.code-snippets
|
|
||||||
|
|
||||||
# Local History for Visual Studio Code
|
|
||||||
.history/
|
|
||||||
|
|
||||||
# Built Visual Studio Code Extensions
|
|
||||||
*.vsix
|
|
||||||
|
|
||||||
### VisualStudioCode Patch ###
|
|
||||||
# Ignore all local history of files
|
|
||||||
.history
|
|
||||||
.ionide
|
|
||||||
|
|
||||||
# End of https://www.toptal.com/developers/gitignore/api/go,goland,visualstudiocode,vim
|
|
||||||
|
|
||||||
|
|||||||
30
backend/cmd/main.go
Normal file
30
backend/cmd/main.go
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
|
||||||
|
"easywish/config"
|
||||||
|
"easywish/internal/logger"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
// Load the configuration
|
||||||
|
if err := config.LoadConfig(); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup logger
|
||||||
|
logger.InitLogger()
|
||||||
|
defer logger.GetLogger().Sync()
|
||||||
|
|
||||||
|
// Connect & migrate database
|
||||||
|
// models.Init()
|
||||||
|
|
||||||
|
// Setup routes
|
||||||
|
r := gin.Default()
|
||||||
|
// serviceController.SetupRoutes(r)
|
||||||
|
// animalController.SetupRoutes(r)
|
||||||
|
r.Run()
|
||||||
|
}
|
||||||
|
|
||||||
92
backend/config/config.go
Normal file
92
backend/config/config.go
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"reflect"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
Hostname string `mapstructure:"HOSTNAME"`
|
||||||
|
Port string `mapstructure:"PORT"`
|
||||||
|
|
||||||
|
DatabaseUrl string `mapstructure:"DATABASE_URL"`
|
||||||
|
RedisUrl string `mapstructure:"REDIS_URL"`
|
||||||
|
MinioUrl string `mapstructure:"MINIO_URL"`
|
||||||
|
|
||||||
|
JwtAlgorithm string `mapstructure:"JWT_ALGORITHM"`
|
||||||
|
JwtSecret string `mapstructure:"JWT_SECRET"`
|
||||||
|
JwtIssuer string `mapstructure:"JWT_ISSUER"`
|
||||||
|
JwtAudience string `mapstructure:"JWT_AUDIENCE"`
|
||||||
|
JwtExpAccess string `mapstructure:"JWT_EXP_ACCESS"`
|
||||||
|
JwtExpRefresh string `mapstructure:"JWT_EXP_REFRESH"`
|
||||||
|
|
||||||
|
Environment string `mapstructure:"ENVIRONMENT"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var config *Config
|
||||||
|
|
||||||
|
// TODO: migrate logging to Zap
|
||||||
|
func LoadConfig() error {
|
||||||
|
|
||||||
|
// Load .env file
|
||||||
|
if err := viper.ReadInConfig(); err != nil {
|
||||||
|
log.Printf("Error reading config file, proceeding with environment variables. %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set default parameters
|
||||||
|
viper.SetDefault("HOSTNAME", "localhost")
|
||||||
|
viper.SetDefault("PORT", "8080")
|
||||||
|
viper.SetDefault("DATABASE_URL", "mydb")
|
||||||
|
viper.SetDefault("REDIS_URL", "myredis")
|
||||||
|
viper.SetDefault("MINIO_URL", "myminio")
|
||||||
|
viper.SetDefault("JWT_ALGORITHM", "HS256")
|
||||||
|
viper.SetDefault("JWT_SECRET", "default_jwt_secret_please_change") // TODO: remove and randomly generate
|
||||||
|
viper.SetDefault("JWT_EXP_ACCESS", "5m")
|
||||||
|
viper.SetDefault("JWT_EXP_REFRESH", "1w")
|
||||||
|
viper.SetDefault("JWT_AUDIENCE", "easywish")
|
||||||
|
viper.SetDefault("JWT_ISSUER", "easywish")
|
||||||
|
|
||||||
|
viper.SetDefault("ENVIRONMENT", "production")
|
||||||
|
|
||||||
|
// Set the file name and type for Viper
|
||||||
|
viper.SetConfigName(".env") // name of config file (without extension)
|
||||||
|
viper.SetConfigType("env") // REQUIRED if the config file does not have the extension
|
||||||
|
viper.AddConfigPath(".") // optionally look for config in the working directory
|
||||||
|
|
||||||
|
// Unmarshal the configuration into the Config struct
|
||||||
|
if err := viper.Unmarshal(&config); err != nil {
|
||||||
|
log.Fatalf("Unable to decode into struct, %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Perform validation
|
||||||
|
if err := validateConfig(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateConfig() error {
|
||||||
|
v := reflect.ValueOf(*config)
|
||||||
|
t := v.Type()
|
||||||
|
|
||||||
|
for i := range v.NumField() {
|
||||||
|
field := v.Field(i)
|
||||||
|
fieldType := t.Field(i)
|
||||||
|
|
||||||
|
// Check if the field is a string and is empty
|
||||||
|
if field.Kind() == reflect.String && field.String() == "" {
|
||||||
|
return fmt.Errorf("Missing required configuration: %s", fieldType.Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetConfig() *Config {
|
||||||
|
return config
|
||||||
|
}
|
||||||
|
|
||||||
@@ -29,6 +29,7 @@ require (
|
|||||||
github.com/go-viper/mapstructure/v2 v2.2.1 // indirect
|
github.com/go-viper/mapstructure/v2 v2.2.1 // indirect
|
||||||
github.com/goccy/go-json v0.10.5 // indirect
|
github.com/goccy/go-json v0.10.5 // indirect
|
||||||
github.com/golang-jwt/jwt/v5 v5.2.2 // indirect
|
github.com/golang-jwt/jwt/v5 v5.2.2 // indirect
|
||||||
|
github.com/joho/godotenv v1.5.1 // indirect
|
||||||
github.com/josharian/intern v1.0.0 // indirect
|
github.com/josharian/intern v1.0.0 // indirect
|
||||||
github.com/json-iterator/go v1.1.12 // indirect
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
github.com/klauspost/cpuid/v2 v2.2.10 // indirect
|
github.com/klauspost/cpuid/v2 v2.2.10 // indirect
|
||||||
|
|||||||
@@ -55,6 +55,8 @@ github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeD
|
|||||||
github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
|
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||||
|
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||||
|
|||||||
28
backend/internal/logger/logger.go
Normal file
28
backend/internal/logger/logger.go
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
package logger
|
||||||
|
|
||||||
|
import (
|
||||||
|
"go.uber.org/zap"
|
||||||
|
"easywish/config"
|
||||||
|
)
|
||||||
|
|
||||||
|
var logger *zap.Logger
|
||||||
|
|
||||||
|
func InitLogger() {
|
||||||
|
var err error
|
||||||
|
cfg := config.GetConfig()
|
||||||
|
|
||||||
|
// TODO: make this configurable
|
||||||
|
if cfg.Environment == "production" {
|
||||||
|
logger, err = zap.NewProduction()
|
||||||
|
} else {
|
||||||
|
logger, err = zap.NewDevelopment()
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetLogger() *zap.Logger {
|
||||||
|
return logger
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user