Browse Source

Services refactoring

Dima 2 năm trước cách đây
mục cha
commit
67865e1507

+ 9 - 3
cmd/app/main.go

@@ -3,17 +3,23 @@ package main
 import (
 	"log"
 
-	"github.com/dmitriygnatenko/internal/app"
+	"github.com/dmitriygnatenko/internal/fiber"
+	sp "github.com/dmitriygnatenko/internal/service_provider"
 	_ "github.com/go-sql-driver/mysql"
 )
 
 func main() {
-	a, err := app.Init()
+	serviceProvider, err := sp.Init()
 	if err != nil {
 		log.Fatal(err)
 	}
 
-	if err = a.Run(); err != nil {
+	fiberApp, err := fiber.Init(serviceProvider)
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	if err = fiberApp.Listen(":" + serviceProvider.GetEnvService().GetAppPort()); err != nil {
 		log.Fatal(err)
 	}
 }

+ 0 - 113
internal/app/app.go

@@ -1,113 +0,0 @@
-package app
-
-import (
-	"database/sql"
-
-	"github.com/dmitriygnatenko/internal/interfaces"
-	"github.com/dmitriygnatenko/internal/repositories"
-	cacheService "github.com/dmitriygnatenko/internal/services/cache"
-	configService "github.com/dmitriygnatenko/internal/services/config"
-	dbService "github.com/dmitriygnatenko/internal/services/db"
-	envService "github.com/dmitriygnatenko/internal/services/env"
-	mailService "github.com/dmitriygnatenko/internal/services/mailer"
-	routerService "github.com/dmitriygnatenko/internal/services/router"
-	"github.com/gofiber/fiber/v2"
-	"github.com/gofiber/fiber/v2/middleware/cors"
-	"github.com/gofiber/fiber/v2/middleware/recover"
-)
-
-const webDir = "../../web"
-
-type App struct {
-	db                   *sql.DB
-	env                  interfaces.IEnv
-	cache                interfaces.ICache
-	mailer               interfaces.IMailer
-	articleRepository    interfaces.IArticleRepository
-	tagRepository        interfaces.ITagRepository
-	articleTagRepository interfaces.IArticleTagRepository
-
-	fiber *fiber.App
-}
-
-func Init() (*App, error) {
-	app := &App{}
-
-	// Init env service
-	env, err := envService.Init()
-	if err != nil {
-		return nil, err
-	}
-	app.env = env
-
-	// Init DB
-	db, err := dbService.Init(app.GetEnvService())
-	if err != nil {
-		return nil, err
-	}
-	app.db = db
-
-	// Init repositories
-	app.articleRepository = repositories.InitArticleRepository(app.GetDBService())
-	app.tagRepository = repositories.InitTagRepository(app.GetDBService())
-	app.articleTagRepository = repositories.InitArticleTagRepository(app.GetDBService())
-
-	// Init cache service
-	app.cache = cacheService.Init()
-
-	// Init mailer
-	app.mailer = mailService.Init(app.GetEnvService())
-
-	// Init fiber
-	app.fiber = fiber.New(configService.Init(app))
-
-	// Init routes and handlers
-	routerService.ApplyRoutes(app)
-
-	// Configure web root
-	app.fiber.Static("/", webDir)
-
-	// Configure CORS middleware
-	app.fiber.Use(cors.New())
-
-	// Configure recover middleware
-	app.fiber.Use(recover.New())
-
-	return app, nil
-}
-
-func (a *App) Run() error {
-	return a.fiber.Listen(":" + a.env.GetAppPort())
-}
-
-func (a *App) GetDBService() *sql.DB {
-	return a.db
-}
-
-func (a *App) GetEnvService() interfaces.IEnv {
-	return a.env
-}
-
-func (a *App) GetCacheService() interfaces.ICache {
-	return a.cache
-}
-
-func (a *App) GetMailerService() interfaces.IMailer {
-	return a.mailer
-}
-
-func (a *App) GetArticleRepository() interfaces.IArticleRepository {
-	return a.articleRepository
-}
-
-func (a *App) GetTagRepository() interfaces.ITagRepository {
-	return a.tagRepository
-}
-
-func (a *App) GetArticleTagRepository() interfaces.IArticleTagRepository {
-	return a.articleTagRepository
-}
-
-func (a *App) GetFiber() *fiber.App {
-	return a.fiber
-}

+ 144 - 0
internal/fiber/fiber.go

@@ -0,0 +1,144 @@
+package fiber
+
+import (
+	"html/template"
+	"log"
+	"strconv"
+	"time"
+
+	"github.com/dmitriygnatenko/internal/interfaces"
+	"github.com/dmitriygnatenko/internal/services/handler"
+	adminHandler "github.com/dmitriygnatenko/internal/services/handler/admin"
+	"github.com/gofiber/fiber/v2"
+	"github.com/gofiber/fiber/v2/middleware/basicauth"
+	"github.com/gofiber/fiber/v2/middleware/cors"
+	"github.com/gofiber/fiber/v2/middleware/monitor"
+	"github.com/gofiber/fiber/v2/middleware/recover"
+	"github.com/gofiber/template/html"
+)
+
+const (
+	appName       = "dmitriygnatenko"
+	templatesPath = "./../../internal/templates"
+	staticPath    = "../../web"
+)
+
+func Init(sp interfaces.IServiceProvider) (*fiber.App, error) {
+	fiberApp := fiber.New(getConfig(sp))
+
+	// Configure web root
+	fiberApp.Static("/", staticPath)
+
+	// Configure CORS middleware
+	fiberApp.Use(cors.New())
+
+	// Configure recover middleware
+	fiberApp.Use(recover.New())
+
+	// Configure handlers
+	fiberApp.Get("/", handler.MainPageHandler(sp))
+	fiberApp.Get("/tag/:tag", handler.TagHandler(sp))
+	fiberApp.Get("/article/:article", handler.ArticleHandler(sp))
+
+	// Admin
+	user := sp.GetEnvService().GetAdminUser()
+	password := sp.GetEnvService().GetAdminPassword()
+
+	if user != "" && password != "" {
+		admin := fiberApp.Group("/admin", basicauth.New(basicauth.Config{
+			Users: map[string]string{
+				user: password,
+			},
+		}))
+
+		admin.Get("/metrics", monitor.New(monitor.Config{}))
+		admin.Get("/", adminHandler.ArticleHandler(sp))
+		admin.All("/article/add", adminHandler.AddArticleHandler(sp))
+		admin.All("/article/edit/:id<int>", adminHandler.EditArticleHandler(sp))
+		admin.All("/article/delete/:id<int>", adminHandler.DeleteArticleHandler(sp))
+		admin.Get("/tag", adminHandler.TagHandler(sp))
+		admin.All("/tag/add", adminHandler.AddTagHandler(sp))
+		admin.All("/tag/edit/:id<int>", adminHandler.EditTagHandler(sp))
+		admin.All("/tag/delete/:id<int>", adminHandler.DeleteTagHandler(sp))
+	}
+
+	return fiberApp, nil
+}
+
+func getConfig(sp interfaces.IServiceProvider) fiber.Config {
+	return fiber.Config{
+		AppName:               appName,
+		DisableStartupMessage: true,
+		Views:                 initEngine(sp.GetEnvService()),
+		ErrorHandler:          initErrorHandler(sp),
+	}
+}
+
+func initEngine(env interfaces.IEnv) *html.Engine {
+	engine := html.New(templatesPath, ".html")
+
+	engine.AddFunc("now", func() time.Time {
+		return time.Now()
+	})
+
+	engine.AddFunc("noescape", func(str string) template.HTML {
+		return template.HTML(str)
+	})
+
+	engine.AddFunc("gridsep", func(i, l int) bool {
+		i++
+		return i%3 == 0 && i != l
+	})
+
+	engine.AddFunc("version", func() string {
+		return env.GetStaticVersion()
+	})
+
+	engine.AddFunc("ga", func() bool {
+		return env.IsGAEnabled()
+	})
+
+	return engine
+}
+
+func initErrorHandler(sp interfaces.IServiceProvider) fiber.ErrorHandler {
+	return func(ctx *fiber.Ctx, err error) error {
+		errCode := fiber.StatusInternalServerError
+		errText := err.Error()
+
+		if e, ok := err.(*fiber.Error); ok {
+			errCode = e.Code
+		}
+
+		var renderData fiber.Map
+
+		if errCode == fiber.StatusNotFound {
+			renderData = fiber.Map{
+				"pageTitle": "Страница не найдена",
+				"code":      fiber.StatusNotFound,
+				"text":      "Запрашиваемая вами страница не найдена",
+			}
+		} else {
+			renderData = fiber.Map{
+				"pageTitle": "Внутренняя ошибка",
+				"code":      fiber.StatusInternalServerError,
+				"text":      "Внутренняя ошибка сервера, идем исправлять...",
+			}
+
+			if errText != "" {
+				sendErr := sp.GetMailerService().Send(
+					sp.GetEnvService().GetAdminEmail(),
+					"Ошибка на сайте dmitriygnatenko.ru",
+					"Код: "+strconv.Itoa(errCode)+"\r\n"+"Текст: "+errText,
+				)
+				if sendErr != nil {
+					log.Print(sendErr)
+				}
+			}
+		}
+
+		renderData["headTitle"] = "От слона к суслику - статьи про PHP, Go, алгоритмы"
+
+		return ctx.Render("error", renderData, "_layout")
+	}
+}

+ 1 - 9
internal/interfaces/app.go → internal/interfaces/sp.go

@@ -1,18 +1,10 @@
 package interfaces
 
-import (
-	"database/sql"
-
-	"github.com/gofiber/fiber/v2"
-)
-
-type IApp interface {
-	GetDBService() *sql.DB
+type IServiceProvider interface {
 	GetEnvService() IEnv
 	GetCacheService() ICache
 	GetMailerService() IMailer
 	GetArticleRepository() IArticleRepository
 	GetTagRepository() ITagRepository
 	GetArticleTagRepository() IArticleTagRepository
-	GetFiber() *fiber.App
 }

+ 72 - 0
internal/service_provider/sp.go

@@ -0,0 +1,72 @@
+package service_provider
+
+import (
+	"github.com/dmitriygnatenko/internal/interfaces"
+	"github.com/dmitriygnatenko/internal/repositories"
+	cacheService "github.com/dmitriygnatenko/internal/services/cache"
+	dbService "github.com/dmitriygnatenko/internal/services/db"
+	envService "github.com/dmitriygnatenko/internal/services/env"
+	mailService "github.com/dmitriygnatenko/internal/services/mailer"
+)
+
+type ServiceProvider struct {
+	env                  interfaces.IEnv
+	cache                interfaces.ICache
+	mailer               interfaces.IMailer
+	articleRepository    interfaces.IArticleRepository
+	tagRepository        interfaces.ITagRepository
+	articleTagRepository interfaces.IArticleTagRepository
+}
+
+func Init() (*ServiceProvider, error) {
+	sp := &ServiceProvider{}
+
+	// Init env service
+	env, err := envService.Init()
+	if err != nil {
+		return nil, err
+	}
+	sp.env = env
+
+	db, err := dbService.Init(env)
+	if err != nil {
+		return nil, err
+	}
+
+	// Init repositories
+	sp.articleRepository = repositories.InitArticleRepository(db)
+	sp.tagRepository = repositories.InitTagRepository(db)
+	sp.articleTagRepository = repositories.InitArticleTagRepository(db)
+
+	// Init cache service
+	sp.cache = cacheService.Init()
+
+	// Init mailer
+	sp.mailer = mailService.Init(sp.env)
+
+	return sp, nil
+}
+
+func (sp *ServiceProvider) GetEnvService() interfaces.IEnv {
+	return sp.env
+}
+
+func (sp *ServiceProvider) GetCacheService() interfaces.ICache {
+	return sp.cache
+}
+
+func (sp *ServiceProvider) GetMailerService() interfaces.IMailer {
+	return sp.mailer
+}
+
+func (sp *ServiceProvider) GetArticleRepository() interfaces.IArticleRepository {
+	return sp.articleRepository
+}
+
+func (sp *ServiceProvider) GetTagRepository() interfaces.ITagRepository {
+	return sp.tagRepository
+}
+
+func (sp *ServiceProvider) GetArticleTagRepository() interfaces.IArticleTagRepository {
+	return sp.articleTagRepository
+}

+ 0 - 96
internal/services/config/config.go

@@ -1,96 +0,0 @@
-package config
-
-import (
-	"html/template"
-	"log"
-	"strconv"
-	"time"
-
-	"github.com/dmitriygnatenko/internal/interfaces"
-	"github.com/gofiber/fiber/v2"
-	"github.com/gofiber/template/html"
-)
-
-const (
-	appName       = "dmitriygnatenko"
-	templatesPath = "./../../internal/templates"
-)
-
-func Init(app interfaces.IApp) fiber.Config {
-	return fiber.Config{
-		AppName:               appName,
-		DisableStartupMessage: true,
-		Views:                 initEngine(app.GetEnvService()),
-		ErrorHandler:          initErrorHandler(app),
-	}
-}
-
-//nolint
-func initEngine(env interfaces.IEnv) *html.Engine {
-	engine := html.New(templatesPath, ".html")
-
-	engine.AddFunc("now", func() time.Time {
-		return time.Now()
-	})
-
-	engine.AddFunc("noescape", func(str string) template.HTML {
-		return template.HTML(str)
-	})
-
-	engine.AddFunc("gridsep", func(i, l int) bool {
-		i++
-		return i%3 == 0 && i != l
-	})
-
-	engine.AddFunc("version", func() string {
-		return env.GetStaticVersion()
-	})
-
-	engine.AddFunc("ga", func() bool {
-		return env.IsGAEnabled()
-	})
-
-	return engine
-}
-
-func initErrorHandler(app interfaces.IApp) fiber.ErrorHandler {
-	return func(ctx *fiber.Ctx, err error) error {
-		errCode := fiber.StatusInternalServerError
-		errText := err.Error()
-
-		if e, ok := err.(*fiber.Error); ok {
-			errCode = e.Code
-		}
-
-		var renderData fiber.Map
-
-		if errCode == fiber.StatusNotFound {
-			renderData = fiber.Map{
-				"pageTitle": "Страница не найдена",
-				"code":      fiber.StatusNotFound,
-				"text":      "Запрашиваемая вами страница не найдена",
-			}
-		} else {
-			renderData = fiber.Map{
-				"pageTitle": "Внутренняя ошибка",
-				"code":      fiber.StatusInternalServerError,
-				"text":      "Внутренняя ошибка сервера, идем исправлять...",
-			}
-
-			if errText != "" {
-				sendErr := app.GetMailerService().Send(
-					app.GetEnvService().GetAdminEmail(),
-					"Ошибка на сайте dmitriygnatenko.ru",
-					"Код: "+strconv.Itoa(errCode)+"\r\n"+"Текст: "+errText,
-				)
-				if sendErr != nil {
-					log.Print(sendErr)
-				}
-			}
-		}
-
-		renderData["headTitle"] = "От слона к суслику - статьи про PHP, Go, алгоритмы"
-
-		return ctx.Render("error", renderData, "_layout")
-	}
-}

+ 22 - 22
internal/services/handler/admin/article.go

@@ -13,9 +13,9 @@ import (
 
 const errArticleExists = "Статья с данным URL уже существует"
 
-func ArticleHandler(app interfaces.IApp) fiber.Handler {
+func ArticleHandler(sp interfaces.IServiceProvider) fiber.Handler {
 	return func(ctx *fiber.Ctx) error {
-		articles, err := app.GetArticleRepository().GetAll(ctx.Context())
+		articles, err := sp.GetArticleRepository().GetAll(ctx.Context())
 		if err != nil {
 			return err
 		}
@@ -32,7 +32,7 @@ func ArticleHandler(app interfaces.IApp) fiber.Handler {
 	}
 }
 
-func AddArticleHandler(app interfaces.IApp) fiber.Handler {
+func AddArticleHandler(sp interfaces.IServiceProvider) fiber.Handler {
 	return func(ctx *fiber.Ctx) error {
 		var validate = validator.New()
 		validateErrors := make(map[string]string)
@@ -46,7 +46,7 @@ func AddArticleHandler(app interfaces.IApp) fiber.Handler {
 			ActiveTags: make(map[int]bool),
 		}
 
-		tags, err := app.GetTagRepository().GetAll(ctx.Context())
+		tags, err := sp.GetTagRepository().GetAll(ctx.Context())
 		if err != nil {
 			return err
 		}
@@ -65,7 +65,7 @@ func AddArticleHandler(app interfaces.IApp) fiber.Handler {
 				validateErrors = helpers.FormatValidateErrors(err, trans)
 			}
 
-			if res, _ := app.GetArticleRepository().GetByURL(ctx.Context(), form.URL); res != nil {
+			if res, _ := sp.GetArticleRepository().GetByURL(ctx.Context(), form.URL); res != nil {
 				validateErrors["ArticleForm.URL"] = errArticleExists
 			}
 
@@ -84,18 +84,18 @@ func AddArticleHandler(app interfaces.IApp) fiber.Handler {
 			}
 
 			if len(validateErrors) == 0 {
-				articleID, articleErr := app.GetArticleRepository().Add(ctx.Context(), mapper.ConvertArticleFormToModel(form))
+				articleID, articleErr := sp.GetArticleRepository().Add(ctx.Context(), mapper.ConvertArticleFormToModel(form))
 				if articleErr != nil {
 					return articleErr
 				}
 
 				if len(form.Tags) > 0 {
-					if err = app.GetArticleTagRepository().Add(ctx.Context(), articleID, tagIDs); err != nil {
+					if err = sp.GetArticleTagRepository().Add(ctx.Context(), articleID, tagIDs); err != nil {
 						return err
 					}
 				}
 
-				app.GetCacheService().FlushAll()
+				sp.GetCacheService().FlushAll()
 
 				if err = ctx.Redirect("/admin"); err != nil {
 					return err
@@ -114,7 +114,7 @@ func AddArticleHandler(app interfaces.IApp) fiber.Handler {
 	}
 }
 
-func EditArticleHandler(app interfaces.IApp) fiber.Handler {
+func EditArticleHandler(sp interfaces.IServiceProvider) fiber.Handler {
 	return func(ctx *fiber.Ctx) error {
 		var validate = validator.New()
 		validateErrors := make(map[string]string)
@@ -129,7 +129,7 @@ func EditArticleHandler(app interfaces.IApp) fiber.Handler {
 			return err
 		}
 
-		article, err := app.GetArticleRepository().GetByID(ctx.Context(), ID)
+		article, err := sp.GetArticleRepository().GetByID(ctx.Context(), ID)
 		if err != nil {
 			return err
 		}
@@ -137,12 +137,12 @@ func EditArticleHandler(app interfaces.IApp) fiber.Handler {
 			return fiber.ErrNotFound
 		}
 
-		articleTags, err := app.GetTagRepository().GetByArticleID(ctx.Context(), ID)
+		articleTags, err := sp.GetTagRepository().GetByArticleID(ctx.Context(), ID)
 		if err != nil {
 			return err
 		}
 
-		tags, err := app.GetTagRepository().GetAll(ctx.Context())
+		tags, err := sp.GetTagRepository().GetAll(ctx.Context())
 		if err != nil {
 			return err
 		}
@@ -172,7 +172,7 @@ func EditArticleHandler(app interfaces.IApp) fiber.Handler {
 				validateErrors = helpers.FormatValidateErrors(err, trans)
 			}
 
-			if res, _ := app.GetArticleRepository().GetByURL(ctx.Context(), form.URL); res != nil {
+			if res, _ := sp.GetArticleRepository().GetByURL(ctx.Context(), form.URL); res != nil {
 				if res.ID != ID {
 					validateErrors["ArticleForm.URL"] = errArticleExists
 				}
@@ -193,7 +193,7 @@ func EditArticleHandler(app interfaces.IApp) fiber.Handler {
 			}
 
 			if len(validateErrors) == 0 {
-				err = app.GetArticleRepository().Update(ctx.Context(), mapper.ConvertArticleFormToModel(*form))
+				err = sp.GetArticleRepository().Update(ctx.Context(), mapper.ConvertArticleFormToModel(*form))
 				if err != nil {
 					return err
 				}
@@ -215,18 +215,18 @@ func EditArticleHandler(app interfaces.IApp) fiber.Handler {
 				}
 
 				if len(tagsToAdd) > 0 {
-					if err = app.GetArticleTagRepository().Add(ctx.Context(), ID, tagsToAdd); err != nil {
+					if err = sp.GetArticleTagRepository().Add(ctx.Context(), ID, tagsToAdd); err != nil {
 						return err
 					}
 				}
 
 				if len(tagsToDelete) > 0 {
-					if err = app.GetArticleTagRepository().Delete(ctx.Context(), ID, tagsToDelete); err != nil {
+					if err = sp.GetArticleTagRepository().Delete(ctx.Context(), ID, tagsToDelete); err != nil {
 						return err
 					}
 				}
 
-				app.GetCacheService().FlushAll()
+				sp.GetCacheService().FlushAll()
 
 				if ctx.FormValue("action", "save") == "save" {
 					if err = ctx.Redirect("/admin"); err != nil {
@@ -247,30 +247,30 @@ func EditArticleHandler(app interfaces.IApp) fiber.Handler {
 	}
 }
 
-func DeleteArticleHandler(app interfaces.IApp) fiber.Handler {
+func DeleteArticleHandler(sp interfaces.IServiceProvider) fiber.Handler {
 	return func(ctx *fiber.Ctx) error {
 		ID, err := strconv.Atoi(ctx.Params("id"))
 		if err != nil {
 			return err
 		}
 
-		article, err := app.GetArticleRepository().GetByID(ctx.Context(), ID)
+		article, err := sp.GetArticleRepository().GetByID(ctx.Context(), ID)
 		if err != nil {
 			return err
 		}
 
 		if ctx.Method() == fiber.MethodPost {
-			err = app.GetArticleTagRepository().DeleteByArticleID(ctx.Context(), ID)
+			err = sp.GetArticleTagRepository().DeleteByArticleID(ctx.Context(), ID)
 			if err != nil {
 				return err
 			}
 
-			err = app.GetArticleRepository().Delete(ctx.Context(), ID)
+			err = sp.GetArticleRepository().Delete(ctx.Context(), ID)
 			if err != nil {
 				return err
 			}
 
-			app.GetCacheService().FlushAll()
+			sp.GetCacheService().FlushAll()
 
 			if err = ctx.Redirect("/admin"); err != nil {
 				return err

+ 16 - 16
internal/services/handler/admin/tag.go

@@ -13,9 +13,9 @@ import (
 
 const errTagExists = "Тег с данным URL уже существует"
 
-func TagHandler(app interfaces.IApp) fiber.Handler {
+func TagHandler(sp interfaces.IServiceProvider) fiber.Handler {
 	return func(ctx *fiber.Ctx) error {
-		tags, err := app.GetTagRepository().GetAll(ctx.Context())
+		tags, err := sp.GetTagRepository().GetAll(ctx.Context())
 		if err != nil {
 			return err
 		}
@@ -32,7 +32,7 @@ func TagHandler(app interfaces.IApp) fiber.Handler {
 	}
 }
 
-func AddTagHandler(app interfaces.IApp) fiber.Handler {
+func AddTagHandler(sp interfaces.IServiceProvider) fiber.Handler {
 	return func(ctx *fiber.Ctx) error {
 		var form models.TagForm
 		var validate = validator.New()
@@ -52,17 +52,17 @@ func AddTagHandler(app interfaces.IApp) fiber.Handler {
 				validateErrors = helpers.FormatValidateErrors(err, trans)
 			}
 
-			if res, _ := app.GetTagRepository().GetByURL(ctx.Context(), form.URL); res != nil {
+			if res, _ := sp.GetTagRepository().GetByURL(ctx.Context(), form.URL); res != nil {
 				validateErrors["TagForm.URL"] = errTagExists
 			}
 
 			if len(validateErrors) == 0 {
-				err = app.GetTagRepository().Add(ctx.Context(), mapper.ConvertTagFormToModel(form))
+				err = sp.GetTagRepository().Add(ctx.Context(), mapper.ConvertTagFormToModel(form))
 				if err != nil {
 					return err
 				}
 
-				app.GetCacheService().FlushAll()
+				sp.GetCacheService().FlushAll()
 
 				if err = ctx.Redirect("/admin/tag"); err != nil {
 					return err
@@ -79,7 +79,7 @@ func AddTagHandler(app interfaces.IApp) fiber.Handler {
 	}
 }
 
-func EditTagHandler(app interfaces.IApp) fiber.Handler {
+func EditTagHandler(sp interfaces.IServiceProvider) fiber.Handler {
 	return func(ctx *fiber.Ctx) error {
 		var validate = validator.New()
 		validateErrors := make(map[string]string)
@@ -94,7 +94,7 @@ func EditTagHandler(app interfaces.IApp) fiber.Handler {
 			return err
 		}
 
-		tag, err := app.GetTagRepository().GetByID(ctx.Context(), ID)
+		tag, err := sp.GetTagRepository().GetByID(ctx.Context(), ID)
 		if err != nil {
 			return err
 		}
@@ -114,19 +114,19 @@ func EditTagHandler(app interfaces.IApp) fiber.Handler {
 				validateErrors = helpers.FormatValidateErrors(err, trans)
 			}
 
-			if res, _ := app.GetTagRepository().GetByURL(ctx.Context(), form.URL); res != nil {
+			if res, _ := sp.GetTagRepository().GetByURL(ctx.Context(), form.URL); res != nil {
 				if res.ID != ID {
 					validateErrors["TagForm.URL"] = errTagExists
 				}
 			}
 
 			if len(validateErrors) == 0 {
-				err = app.GetTagRepository().Update(ctx.Context(), mapper.ConvertTagFormToModel(form))
+				err = sp.GetTagRepository().Update(ctx.Context(), mapper.ConvertTagFormToModel(form))
 				if err != nil {
 					return err
 				}
 
-				app.GetCacheService().FlushAll()
+				sp.GetCacheService().FlushAll()
 
 				if err = ctx.Redirect("/admin/tag"); err != nil {
 					return err
@@ -143,30 +143,30 @@ func EditTagHandler(app interfaces.IApp) fiber.Handler {
 	}
 }
 
-func DeleteTagHandler(app interfaces.IApp) fiber.Handler {
+func DeleteTagHandler(sp interfaces.IServiceProvider) fiber.Handler {
 	return func(ctx *fiber.Ctx) error {
 		ID, err := strconv.Atoi(ctx.Params("id"))
 		if err != nil {
 			return err
 		}
 
-		tag, err := app.GetTagRepository().GetByID(ctx.Context(), ID)
+		tag, err := sp.GetTagRepository().GetByID(ctx.Context(), ID)
 		if err != nil {
 			return err
 		}
 
-		used, err := app.GetTagRepository().IsUsed(ctx.Context(), ID)
+		used, err := sp.GetTagRepository().IsUsed(ctx.Context(), ID)
 		if err != nil {
 			return err
 		}
 
 		if ctx.Method() == fiber.MethodPost {
-			err = app.GetTagRepository().Delete(ctx.Context(), ID)
+			err = sp.GetTagRepository().Delete(ctx.Context(), ID)
 			if err != nil {
 				return err
 			}
 
-			app.GetCacheService().FlushAll()
+			sp.GetCacheService().FlushAll()
 
 			if err = ctx.Redirect("/admin/tag"); err != nil {
 				return err

+ 6 - 6
internal/services/handler/article.go

@@ -13,14 +13,14 @@ const (
 	articleCacheKey  = "article"
 )
 
-func ArticleHandler(app interfaces.IApp) fiber.Handler {
+func ArticleHandler(sp interfaces.IServiceProvider) fiber.Handler {
 	return func(ctx *fiber.Ctx) error {
 		articleReq := ctx.Params("article")
 
-		renderData, found := app.GetCacheService().Get(articleCacheKey + articleReq)
+		renderData, found := sp.GetCacheService().Get(articleCacheKey + articleReq)
 
 		if !found {
-			article, err := app.GetArticleRepository().GetByURL(ctx.Context(), articleReq)
+			article, err := sp.GetArticleRepository().GetByURL(ctx.Context(), articleReq)
 			if err != nil {
 				if err == sql.ErrNoRows {
 					return fiber.ErrNotFound
@@ -38,7 +38,7 @@ func ArticleHandler(app interfaces.IApp) fiber.Handler {
 			}
 
 			// All used tags
-			tags, err := app.GetTagRepository().GetAllUsed(ctx.Context())
+			tags, err := sp.GetTagRepository().GetAllUsed(ctx.Context())
 			if err != nil {
 				return err
 			}
@@ -49,7 +49,7 @@ func ArticleHandler(app interfaces.IApp) fiber.Handler {
 			}
 
 			// Last articles
-			articles, err := app.GetArticleRepository().GetAllPreview(ctx.Context())
+			articles, err := sp.GetArticleRepository().GetAllPreview(ctx.Context())
 			if err != nil {
 				return err
 			}
@@ -72,7 +72,7 @@ func ArticleHandler(app interfaces.IApp) fiber.Handler {
 				"sidebarTags":     tagsDTO,
 			}
 
-			app.GetCacheService().Set(articleCacheKey+articleReq, renderData)
+			sp.GetCacheService().Set(articleCacheKey+articleReq, renderData)
 		}
 
 		return ctx.Render("article", renderData, "_layout")

+ 4 - 5
internal/services/handler/main_page.go

@@ -8,12 +8,12 @@ import (
 
 const allPreviewArticlesCacheKey = "all-preview-articles"
 
-func MainPageHandler(app interfaces.IApp) fiber.Handler {
+func MainPageHandler(sp interfaces.IServiceProvider) fiber.Handler {
 	return func(ctx *fiber.Ctx) error {
-		renderData, found := app.GetCacheService().Get(allPreviewArticlesCacheKey)
+		renderData, found := sp.GetCacheService().Get(allPreviewArticlesCacheKey)
 
 		if !found {
-			articles, err := app.GetArticleRepository().GetAllPreview(ctx.Context())
+			articles, err := sp.GetArticleRepository().GetAllPreview(ctx.Context())
 			if err != nil {
 				return err
 			}
@@ -31,10 +31,9 @@ func MainPageHandler(app interfaces.IApp) fiber.Handler {
 				"articles":        articlesDTO,
 			}
 
-			app.GetCacheService().Set(allPreviewArticlesCacheKey, renderData)
+			sp.GetCacheService().Set(allPreviewArticlesCacheKey, renderData)
 		}
 
 		return ctx.Render("index", renderData, "_layout")
-
 	}
 }

+ 5 - 5
internal/services/handler/tag.go

@@ -10,14 +10,14 @@ import (
 
 const tagCacheKey = "tag"
 
-func TagHandler(app interfaces.IApp) fiber.Handler {
+func TagHandler(sp interfaces.IServiceProvider) fiber.Handler {
 	return func(ctx *fiber.Ctx) error {
 		tagReq := ctx.Params("tag")
 
-		renderData, found := app.GetCacheService().Get(tagCacheKey + tagReq)
+		renderData, found := sp.GetCacheService().Get(tagCacheKey + tagReq)
 
 		if !found {
-			tag, err := app.GetTagRepository().GetByURL(ctx.Context(), tagReq)
+			tag, err := sp.GetTagRepository().GetByURL(ctx.Context(), tagReq)
 			if err != nil {
 				if err == sql.ErrNoRows {
 					return fiber.ErrNotFound
@@ -25,7 +25,7 @@ func TagHandler(app interfaces.IApp) fiber.Handler {
 				return err
 			}
 
-			articles, err := app.GetArticleRepository().GetPreviewByTagID(ctx.Context(), tag.ID)
+			articles, err := sp.GetArticleRepository().GetPreviewByTagID(ctx.Context(), tag.ID)
 			if err != nil {
 				return err
 			}
@@ -43,7 +43,7 @@ func TagHandler(app interfaces.IApp) fiber.Handler {
 				"articles":        articlesDTO,
 			}
 
-			app.GetCacheService().Set(tagCacheKey+tagReq, renderData)
+			sp.GetCacheService().Set(tagCacheKey+tagReq, renderData)
 		}
 
 		return ctx.Render("tag", renderData, "_layout")

+ 0 - 48
internal/services/router/router.go

@@ -1,48 +0,0 @@
-package router
-
-import (
-	"github.com/dmitriygnatenko/internal/interfaces"
-	"github.com/dmitriygnatenko/internal/services/handler"
-	adminHandler "github.com/dmitriygnatenko/internal/services/handler/admin"
-	"github.com/gofiber/fiber/v2"
-	"github.com/gofiber/fiber/v2/middleware/basicauth"
-	"github.com/gofiber/fiber/v2/middleware/monitor"
-)
-
-type Route struct {
-	Method   string
-	Path     string
-	Handlers []fiber.Handler
-}
-
-func ApplyRoutes(app interfaces.IApp) {
-	f := app.GetFiber()
-
-	f.Get("/", handler.MainPageHandler(app))
-	f.Get("/tag/:tag", handler.TagHandler(app))
-	f.Get("/article/:article", handler.ArticleHandler(app))
-
-	// Admin
-	user := app.GetEnvService().GetAdminUser()
-	password := app.GetEnvService().GetAdminPassword()
-
-	if user != "" && password != "" {
-		admin := f.Group("/admin", basicauth.New(basicauth.Config{
-			Users: map[string]string{
-				user: password,
-			},
-		}))
-
-		admin.Get("/metrics", monitor.New(monitor.Config{}))
-
-		admin.Get("/", adminHandler.ArticleHandler(app))
-		admin.All("/article/add", adminHandler.AddArticleHandler(app))
-		admin.All("/article/edit/:id<int>", adminHandler.EditArticleHandler(app))
-		admin.All("/article/delete/:id<int>", adminHandler.DeleteArticleHandler(app))
-
-		admin.Get("/tag", adminHandler.TagHandler(app))
-		admin.All("/tag/add", adminHandler.AddTagHandler(app))
-		admin.All("/tag/edit/:id<int>", adminHandler.EditTagHandler(app))
-		admin.All("/tag/delete/:id<int>", adminHandler.DeleteTagHandler(app))
-	}
-}