feat: go-chi and first routes setup

This commit is contained in:
Florian Sylvain
2023-08-06 05:00:15 +02:00
parent 5b4b5a8622
commit 195c247235
9 changed files with 189 additions and 38 deletions
@@ -18,9 +18,24 @@ func NewArticleRepository() *ArticleRepository {
return &a return &a
} }
func (a *ArticleRepository) connectClient() {
err := a.client.Connect()
if err != nil {
panic(err)
}
}
func (a *ArticleRepository) disconnectClient() {
err := a.client.Disconnect()
if err != nil {
panic(err)
}
a.client = db.NewClient()
}
func (a *ArticleRepository) Get(id int) Article { func (a *ArticleRepository) Get(id int) Article {
a.client.Connect() a.connectClient()
defer a.client.Disconnect() defer a.disconnectClient()
article, err := a.client.Article.FindUnique(db.Article.ID.Equals(id)).Exec(context.Background()) article, err := a.client.Article.FindUnique(db.Article.ID.Equals(id)).Exec(context.Background())
if err != nil { if err != nil {
@@ -31,8 +46,8 @@ func (a *ArticleRepository) Get(id int) Article {
} }
func (a *ArticleRepository) Create(article Article) Article { func (a *ArticleRepository) Create(article Article) Article {
a.client.Connect() a.connectClient()
defer a.client.Disconnect() defer a.disconnectClient()
articleDb, err := a.client.Article.CreateOne( articleDb, err := a.client.Article.CreateOne(
db.Article.Title.Set(article.Title), db.Article.Title.Set(article.Title),
@@ -45,4 +60,21 @@ func (a *ArticleRepository) Create(article Article) Article {
return FromDb(articleDb.ID, articleDb.Title, articleDb.Body, articleDb.CreatedAt.String(), articleDb.UpdatedAt.String()) return FromDb(articleDb.ID, articleDb.Title, articleDb.Body, articleDb.CreatedAt.String(), articleDb.UpdatedAt.String())
} }
func (a *ArticleRepository) GetAll() []Article {
a.connectClient()
defer a.disconnectClient()
articlesDb, err := a.client.Article.FindMany().Exec(context.Background())
if err != nil {
panic(err)
}
var articles []Article
for _, articleDb := range articlesDb {
articles = append(articles, FromDb(articleDb.ID, articleDb.Title, articleDb.Body, articleDb.CreatedAt.String(), articleDb.UpdatedAt.String()))
}
return articles
}
var _ IArticleRepository = &ArticleRepository{} var _ IArticleRepository = &ArticleRepository{}
+49 -4
View File
@@ -3,12 +3,57 @@ package api
import ( import (
. "GohCMS2/domain/article" . "GohCMS2/domain/article"
. "GohCMS2/useCases" . "GohCMS2/useCases"
"encoding/json"
"github.com/go-chi/chi/v5"
"net/http"
"strconv"
) )
func GetArticle(id int) Article { func getArticle(w http.ResponseWriter, r *http.Request) {
return container.GetArticleUseCase.GetArticle(id) id, err := strconv.Atoi(chi.URLParam(r, "id"))
if err != nil {
http.Error(w, err.Error(), http.StatusNotFound)
return
}
article := container.GetArticleUseCase.GetArticle(id)
articleJson, err := json.Marshal(article)
if err != nil {
http.Error(w, err.Error(), http.StatusNotFound)
return
}
_, _ = w.Write(articleJson)
} }
func CreateArticle(title string, body string) Article { func postArticle(w http.ResponseWriter, r *http.Request) {
return container.CreateArticleUseCase.CreateAarticle(CreateArticleCommand{Title: title, Body: body}) var article Article
err := json.NewDecoder(r.Body).Decode(&article)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
createdArticle := container.CreateArticleUseCase.CreateAarticle(CreateArticleCommand{
Title: article.Title,
Body: article.Body,
})
articleJson, _ := json.Marshal(createdArticle)
_, _ = w.Write(articleJson)
}
func listArticles(w http.ResponseWriter, _ *http.Request) {
articles := container.ListArticlesUseCase.ListArticles()
articlesJson, _ := json.Marshal(articles)
_, _ = w.Write(articlesJson)
}
func NewArticleRouter() http.Handler {
r := chi.NewRouter()
r.Get("/{id}", getArticle)
r.Post("/", postArticle)
r.Get("/", listArticles)
return r
} }
+20 -20
View File
@@ -2,40 +2,40 @@ package api
import ( import (
. "GohCMS2/useCases" . "GohCMS2/useCases"
"errors"
"go.uber.org/dig" "go.uber.org/dig"
) )
type Container struct { type Container struct {
CreateArticleUseCase *CreateArticleUseCase CreateArticleUseCase *CreateArticleUseCase
GetArticleUseCase *GetArticleUseCase GetArticleUseCase *GetArticleUseCase
ListArticlesUseCase *ListArticlesUseCase
} }
var container *Container var container *Container
func InitContainer() *Container { func createContainer(
if container != nil { createArticle *CreateArticleUseCase,
getArticle *GetArticleUseCase,
listArticle *ListArticlesUseCase,
) *Container {
container = &Container{
CreateArticleUseCase: createArticle,
GetArticleUseCase: getArticle,
ListArticlesUseCase: listArticle,
}
return container return container
}
func InitContainer() {
if container != nil {
return
} }
digContainer := dig.New() digContainer := dig.New()
err1 := digContainer.Provide(NewCreateArticleUseCase) _ = digContainer.Provide(NewCreateArticleUseCase)
err2 := digContainer.Provide(NewGetArticleUseCase) _ = digContainer.Provide(NewGetArticleUseCase)
_ = digContainer.Provide(NewListArticlesUseCase)
if err := errors.Join(err1, err2); err != nil { _ = digContainer.Invoke(createContainer)
panic(err)
}
err := digContainer.Invoke(func(createArticle *CreateArticleUseCase, getArticle *GetArticleUseCase) {
container = &Container{
CreateArticleUseCase: createArticle,
GetArticleUseCase: getArticle,
}
})
if err != nil {
panic(err)
}
return container
} }
+20 -2
View File
@@ -2,12 +2,30 @@ package main
import ( import (
"GohCMS2/api" "GohCMS2/api"
"encoding/json"
"fmt" "fmt"
"github.com/go-chi/chi/v5"
"github.com/go-chi/httplog"
"net/http"
) )
func main() { func main() {
api.InitContainer() api.InitContainer()
fmt.Println(api.CreateArticle("Title", "Content")) r := chi.NewRouter()
fmt.Println(api.GetArticle(1)) r.Get("/", func(w http.ResponseWriter, r *http.Request) {
msg, _ := json.Marshal(map[string]string{"message": "Hello World"})
_, _ = w.Write(msg)
})
r.Mount("/article", api.NewArticleRouter())
apiRouter := chi.NewRouter()
apiRouter.Use(httplog.RequestLogger(httplog.NewLogger("GohCMS2")))
apiRouter.Mount("/v1", r)
fmt.Println("Server starting on port 8080")
err := http.ListenAndServe(":8080", apiRouter)
if err != nil {
panic(err)
}
} }
+7 -7
View File
@@ -1,11 +1,11 @@
package article package article
type Article struct { type Article struct {
Id int Id int `json:"id"`
Title string Title string `json:"title"`
Body string Body string `json:"body"`
createdAt string CreatedAt string `json:"created_at"`
updatedAt string UpdatedAt string `json:"updated_at"`
} }
func FromApi( func FromApi(
@@ -29,7 +29,7 @@ func FromDb(
Id: id, Id: id,
Title: title, Title: title,
Body: body, Body: body,
createdAt: createdAt, CreatedAt: createdAt,
updatedAt: updatedAt, UpdatedAt: updatedAt,
} }
} }
+1
View File
@@ -6,5 +6,6 @@ import (
type IArticleRepository interface { type IArticleRepository interface {
Get(id int) Article Get(id int) Article
GetAll() []Article
Create(article Article) Article Create(article Article) Article
} }
+12 -1
View File
@@ -11,4 +11,15 @@ require (
golang.org/x/text v0.10.0 golang.org/x/text v0.10.0
) )
require go.uber.org/dig v1.17.0 require (
github.com/go-chi/httplog v0.3.1
go.uber.org/dig v1.17.0
)
require (
github.com/go-chi/chi/v5 v5.0.10
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/rs/zerolog v1.29.1 // indirect
golang.org/x/sys v0.10.0 // indirect
)
+24
View File
@@ -1,12 +1,30 @@
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-chi/chi/v5 v5.0.7/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
github.com/go-chi/chi/v5 v5.0.10 h1:rLz5avzKpjqxrYwXNfmjkrYYXOyLJd37pz53UFHC6vk=
github.com/go-chi/chi/v5 v5.0.10/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
github.com/go-chi/httplog v0.3.1 h1:uC3IUWCZagtbCinb3ypFh36SEcgd6StWw2Bu0XSXRtg=
github.com/go-chi/httplog v0.3.1/go.mod h1:UoiQQ/MTZH5V6JbNB2FzF0DynTh5okpXxlhsyxoP5m8=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/iancoleman/strcase v0.0.0-20190422225806-e506e3ef7365 h1:ECW73yc9MY7935nNYXUkK7Dz17YuSUI9yqRqYS8aBww= github.com/iancoleman/strcase v0.0.0-20190422225806-e506e3ef7365 h1:ECW73yc9MY7935nNYXUkK7Dz17YuSUI9yqRqYS8aBww=
github.com/iancoleman/strcase v0.0.0-20190422225806-e506e3ef7365/go.mod h1:SK73tn/9oHe+/Y0h39VT4UCxmurVJkR5NA7kMEAOgSE= github.com/iancoleman/strcase v0.0.0-20190422225806-e506e3ef7365/go.mod h1:SK73tn/9oHe+/Y0h39VT4UCxmurVJkR5NA7kMEAOgSE=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.29.1 h1:cO+d60CHkknCbvzEWxP0S9K6KqyTjrCNUy1LdQLCGPc=
github.com/rs/zerolog v1.29.1/go.mod h1:Le6ESbR7hc+DP6Lt1THiV8CQSdkkNrd3R0XbEgp3ZBU=
github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/steebchen/prisma-client-go v0.21.0 h1:mWBW4eDbKKdLJ8ET2kj0U8myDIVEPuZFRT7En7Yf7YU= github.com/steebchen/prisma-client-go v0.21.0 h1:mWBW4eDbKKdLJ8ET2kj0U8myDIVEPuZFRT7En7Yf7YU=
@@ -37,9 +55,15 @@ golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
+20
View File
@@ -0,0 +1,20 @@
package useCases
import (
. "GohCMS2/adapters/secondary/gateways"
. "GohCMS2/domain/article"
)
type ListArticlesUseCase struct {
articleRepository ArticleRepository
}
func NewListArticlesUseCase() *ListArticlesUseCase {
return &ListArticlesUseCase{
articleRepository: *NewArticleRepository(),
}
}
func (g *ListArticlesUseCase) ListArticles() []Article {
return g.articleRepository.GetAll()
}