Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: removed gin, cleaned repo and file tree #52

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,15 @@

## I - Introduction

The purpose of this repository is to provide a **solid**, **complete** and **adaptable** base of a [Golang](https://golang.org/)-oriented product in a **project-managed** repository, in order to start a new project with a **maximum time saving**.
The purpose of this repository is to provide a **solid**, **complete**, **beginner friendly**, and **adaptable** base of a [Golang](https://golang.org/)-oriented product in a **project-managed** repository, in order to start a new project with a **maximum time saving**.

This repository provides **commit writting** and **branch naming conventions**, **issues** and **pull request templates**, and a **custom issues labels preset**.

But also **CI/CD** and **release** using [GitHub Actions](https://github.com/features/actions), [GitHub Container Registry](https://github.com/features/packages) and [Docker](https://www.docker.com/).

And finally, a simple **RESTful API**, using [Golang](https://golang.org/), [Postgres](https://www.postgresql.org/) and [Adminer](https://www.adminer.org/), build with [Docker](https://www.docker.com/) and [Docker Compose](https://docs.docker.com/compose/), using a [Makefile](<https://en.wikipedia.org/wiki/Make_(software)>).

> This repository gathers all the good practices that I have learned over time, both in terms of **organization** and **good maintenance** of a project over time as well as in terms of **automation, availability** and **consistancy**.
> This repository gathers all the good practices that [@nooderg](https://github.com/nooderg/) and [I](https://github.com/blyndusk) have learned over time, both in terms of **organization** and **good maintenance** of a project over time as well as in terms of **automation, availability** and **consistancy**.

## II - Table of content

Expand Down
32 changes: 17 additions & 15 deletions cmd/api/main.go
Original file line number Diff line number Diff line change
@@ -1,32 +1,34 @@
package main

import (
"encoding/json"
"log"
"net/http"

"github.com/blyndusk/go-yave/internal/database"
"github.com/blyndusk/go-yave/internal/infrastructure/database"
"github.com/blyndusk/go-yave/internal/router"
"github.com/gin-contrib/cors"
"github.com/gin-gonic/gin"
"github.com/gorilla/handlers"
"github.com/gorilla/mux"
)

func main() {
database.Connect(true)
setupServer()
}

func setupServer() *gin.Engine {
database.Connect()
database.Migrate()
func setupServer() {
r := mux.NewRouter()

r := gin.Default()
r.Use(cors.Default())

r.GET("/", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"message": "[ go-yave | api ]",
})
r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
json.NewEncoder(w).Encode("All good!")
})

headersOk := handlers.AllowedHeaders([]string{"*"})
originsOk := handlers.AllowedOrigins([]string{"*"})
methodsOk := handlers.AllowedMethods([]string{"*"})

r.StrictSlash(true)

router.Setup(r)
r.Run(":3333")
return r
log.Fatal(http.ListenAndServe(":3333", handlers.CORS(originsOk, headersOk, methodsOk)(r)))
}
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ go 1.13
require (
github.com/gin-contrib/cors v1.3.1
github.com/gin-gonic/gin v1.7.7
github.com/google/uuid v1.3.0 // indirect
github.com/gorilla/handlers v1.5.1 // indirect
github.com/gorilla/mux v1.8.0 // indirect
github.com/joho/godotenv v1.4.0
github.com/sirupsen/logrus v1.8.1
gorm.io/driver/postgres v1.3.4
Expand Down
8 changes: 8 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7Do
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/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ=
github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/gin-contrib/cors v1.3.1 h1:doAsuITavI4IOcd0Y19U4B+O0dNWihRyX//nn4sEmgA=
github.com/gin-contrib/cors v1.3.1/go.mod h1:jjEJ4268OPZUcU7k9Pm653S7lXUGcqMADzFA61xsmDk=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
Expand Down Expand Up @@ -36,6 +38,12 @@ github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4=
github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q=
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0=
github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
Expand Down
51 changes: 30 additions & 21 deletions internal/controllers/fixtures.go
Original file line number Diff line number Diff line change
@@ -1,44 +1,53 @@
package controllers

import (
"encoding/json"
"log"
"net/http"

"github.com/blyndusk/go-yave/internal/database"
"github.com/blyndusk/go-yave/pkg/models"
"github.com/gin-gonic/gin"
"github.com/blyndusk/go-yave/internal/infrastructure/persistence"
"github.com/blyndusk/go-yave/internal/models"
)

func LoadData(c *gin.Context) {
users := models.Users{
func LoadData(w http.ResponseWriter, r *http.Request) {
users := []*models.User{
{
Name: "Alex",
Age: 18,
FirstName: "Alex",
Age: 18,
},
{
Name: "Aled",
Age: 23,
FirstName: "Aled",
Age: 23,
},
{
Name: "Klowé",
Age: 21,
FirstName: "Klowé",
Age: 21,
},
{
Name: "Louwise",
Age: 20,
FirstName: "Louwise",
Age: 20,
},
{
Name: "Yowann",
Age: 20,
FirstName: "Yowann",
Age: 20,
},
{
Name: "Zedouin",
Age: 23,
FirstName: "Zedouin",
Age: 23,
},
{
Name: "Jajon",
Age: 32,
FirstName: "Jajon",
Age: 32,
},
}
database.Db.Create(&users)
c.JSON(http.StatusOK, users)

for _, user := range users {
err := persistence.CreateUser(user)
if err != nil {
log.Println(err.Error())
json.NewEncoder(w).Encode("aled")
return
}
}
json.NewEncoder(w).Encode(users)
}
91 changes: 65 additions & 26 deletions internal/controllers/users.go
Original file line number Diff line number Diff line change
@@ -1,43 +1,82 @@
package controllers

import (
"encoding/json"
"net/http"
"strconv"

"github.com/gin-gonic/gin"

"github.com/blyndusk/go-yave/internal/middlewares"
"github.com/blyndusk/go-yave/pkg/models"
"github.com/blyndusk/go-yave/internal/infrastructure/persistence"
"github.com/blyndusk/go-yave/internal/models"
"github.com/gorilla/mux"
)

func CreateUser(c *gin.Context) {
func CreateUser(w http.ResponseWriter, r *http.Request) {
var input models.UserInput
middlewares.CreateUser(c, &input)
c.JSON(http.StatusOK, input)
err := json.NewDecoder(r.Body).Decode(&input)
if err != nil {
json.NewEncoder(w).Encode(err.Error())
return
}

newUser := input.User()

err = persistence.CreateUser(&newUser)
json.NewEncoder(w).Encode(newUser)
}

func GetAllUsers(c *gin.Context) {
var users models.Users
middlewares.GetAllUsers(c, &users)
c.JSON(http.StatusOK, users)
func GetAllUsers(w http.ResponseWriter, r *http.Request) {
users, err := persistence.GetAllUsers()
if err != nil {
json.NewEncoder(w).Encode(err.Error())
return
}
json.NewEncoder(w).Encode(users)
}

func GetUserById(c *gin.Context) {
var user models.User
middlewares.GetUserById(c, &user)
c.JSON(http.StatusOK, user)
func GetUserById(w http.ResponseWriter, r *http.Request) {
userID, err := strconv.Atoi(mux.Vars(r)["id"])
if err != nil {
json.NewEncoder(w).Encode(err.Error())
return
}

user, err := persistence.GetUserById(uint(userID))
if err != nil {
json.NewEncoder(w).Encode(err.Error())
return
}

json.NewEncoder(w).Encode(user)
}

func UpdateUser(c *gin.Context) {
var user models.User
var input models.UserInput
middlewares.UpdateUser(c, &user, &input)
c.JSON(http.StatusOK, user)
func UpdateUser(w http.ResponseWriter, r *http.Request) {
var userInput models.UserInput
err := json.NewDecoder(r.Body).Decode(&userInput)
if err != nil {
json.NewEncoder(w).Encode(err.Error())
return
}

user := userInput.User()
err = persistence.UpdateUser(&user)
if err != nil {
json.NewEncoder(w).Encode(err.Error())
return
}

json.NewEncoder(w).Encode(user)
}

func DeleteUser(c *gin.Context) {
var user models.User
middlewares.DeleteUser(c, &user)
c.JSON(http.StatusOK, gin.H{
"message": "User deleted successfully",
})
func DeleteUser(w http.ResponseWriter, r *http.Request) {
userID, err := strconv.Atoi(mux.Vars(r)["id"])
if err != nil {
json.NewEncoder(w).Encode(err.Error())
return
}

err = persistence.DeleteUser(uint(userID))
if err != nil {
json.NewEncoder(w).Encode(err.Error())
return
}
}
11 changes: 0 additions & 11 deletions internal/database/migration.go

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@ import (
"fmt"
"time"

log "github.com/sirupsen/logrus"
"gorm.io/driver/postgres"
"gorm.io/gorm"

"github.com/blyndusk/go-yave/pkg/helpers"
"github.com/sirupsen/logrus"
)

var Db *gorm.DB
var DBClient *gorm.DB

func Connect() error {
func Connect(migrate bool) error {
dbURL := fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%s sslmode=disable",
helpers.EnvVar("DB_HOST"),
helpers.EnvVar("DB_USER"),
Expand All @@ -24,18 +24,41 @@ func Connect() error {
var tmpDb *gorm.DB
var err error

for i := 1; i <= 5; i++ {
for i := 0; i <= 5; i++ {
tmpDb, err = gorm.Open(postgres.Open(dbURL), &gorm.Config{})
if err != nil {
log.Warn(fmt.Sprintf("Failed to connect to database. Retry... (%d/5)", i))
logrus.Warn(fmt.Sprintf("Failed to connect to database. Retry... (%d/5)", i))
time.Sleep(5 * time.Second)
continue
}
if migrate {
for i := 0; i <= 5; i++ {
err = Migrate(tmpDb)
if err != nil {
continue
}
logrus.Info("Migrations done !")
break
}
}
break
}
helpers.ExitOnError("Failed to connecto to database", err)

Db = tmpDb
log.Info("Connected to database !")
DBClient = tmpDb
logrus.Info("connected to database !")
return nil
}

func GetDBClient() *gorm.DB {
db, err := DBClient.DB()
if err != nil {
return nil
}
if db.Ping() != nil {
Connect(false)
return DBClient
} else {
return DBClient
}
}
11 changes: 11 additions & 0 deletions internal/infrastructure/database/migration.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package database

import (
"github.com/blyndusk/go-yave/internal/models"
"gorm.io/gorm"
)

func Migrate(Db *gorm.DB) error {
// Add your models here for gorm to create the tables for you.
return Db.AutoMigrate(&models.User{})
}
Loading