Skip to content

Commit 0b2fb00

Browse files
committed
I creating API with Golang Gin Framework
0 parents  commit 0b2fb00

20 files changed

+437
-0
lines changed

.idea/.gitignore

+8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/GraphQL-For-Go.iml

+9
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/modules.xml

+8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/vcs.xml

+6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

controller/video-controller.go

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package controller
2+
3+
import (
4+
"github.com/gin-gonic/gin"
5+
"github.com/go-playground/validator/v10"
6+
"gitlab.com/pragmaticreviews/golang-gin-poc/entity"
7+
"gitlab.com/pragmaticreviews/golang-gin-poc/service"
8+
"gitlab.com/pragmaticreviews/golang-gin-poc/validators"
9+
"net/http"
10+
)
11+
12+
type VideoController interface {
13+
FindAll() []entity.Video
14+
Save(ctx *gin.Context) error
15+
ShowAll(ctx *gin.Context)
16+
}
17+
18+
type controller struct {
19+
service service.VideoService
20+
}
21+
22+
var validate *validator.Validate
23+
24+
func New(service service.VideoService) VideoController {
25+
validate = validator.New()
26+
validate.RegisterValidation("is-cool", validators.ValidateCoolTitle)
27+
return &controller{
28+
service: service,
29+
}
30+
}
31+
32+
func (c *controller) FindAll() []entity.Video {
33+
return c.service.FindAll()
34+
}
35+
36+
func (c *controller) Save(ctx *gin.Context) error {
37+
var video entity.Video
38+
err := ctx.ShouldBindJSON(&video)
39+
if err != nil {
40+
return err
41+
}
42+
err = validate.Struct(video)
43+
if err != nil {
44+
return err
45+
}
46+
c.service.Save(video)
47+
return nil
48+
}
49+
func (c *controller) ShowAll(ctx *gin.Context) {
50+
videos := c.service.FindAll()
51+
data := gin.H{
52+
"title": "Video Page",
53+
"videos": videos,
54+
}
55+
ctx.HTML(http.StatusOK, "index.html", data)
56+
}

entity/video.go

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package entity
2+
3+
type Person struct {
4+
Firstname string `json:"firstname"binding:"required"`
5+
Lastname string `json:"lastname"binding:"required"`
6+
Age int8 `json:"age"binding:"gte=1,lte=130"`
7+
Email string `json:"email"validate:"required,email"`
8+
}
9+
type Video struct {
10+
Title string `json:"title"binding:"min=2,max=200"validate:"is-cool"`
11+
Description string `json:"description"binding:"max=200"`
12+
URL string `json:"url"binding:"required,url"`
13+
Author Person `json:"author" binding:"required"`
14+
}

gin-log

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
2+
- using env: export GIN_MODE=release
3+
- using code: gin.SetMode(gin.ReleaseMode)
4+
5+
[GIN-debug] GET /css/*filepath --> github.com/gin-gonic/gin.(*RouterGroup).createStaticHandler.func1 (5 handlers)
6+
[GIN-debug] HEAD /css/*filepath --> github.com/gin-gonic/gin.(*RouterGroup).createStaticHandler.func1 (5 handlers)
7+
[GIN-debug] Loaded HTML Templates (4):
8+
-
9+
- footer.html
10+
- header.html
11+
- index.html
12+
13+
[GIN-debug] GET /api/videos --> main.main.func1 (5 handlers)
14+
[GIN-debug] POST /api/videos --> main.main.func2 (5 handlers)
15+
[GIN-debug] GET /view/videos --> gitlab.com/pragmaticreviews/golang-gin-poc/controller.VideoController.ShowAll-fm (5 handlers)
16+
[GIN-debug] [WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.
17+
Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.
18+
[GIN-debug] Listening and serving HTTP on :8080
19+
::1 - [28 Jan 22 14:08 +03] POST /api/videos 200 15.2434ms
20+
::1 - [28 Jan 22 14:08 +03] GET /view/videos 200 11.0849ms
21+
::1 - [28 Jan 22 14:08 +03] GET /view/videos 200 9.7141ms
22+
::1 - [28 Jan 22 14:08 +03] GET /view/videos 200 18.1536ms
23+
::1 - [28 Jan 22 14:08 +03] GET /view/videos 200 3.6197ms

gin.log

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
2+
- using env: export GIN_MODE=release
3+
- using code: gin.SetMode(gin.ReleaseMode)
4+
5+
[GIN-debug] GET /css/*filepath --> github.com/gin-gonic/gin.(*RouterGroup).createStaticHandler.func1 (3 handlers)
6+
[GIN-debug] HEAD /css/*filepath --> github.com/gin-gonic/gin.(*RouterGroup).createStaticHandler.func1 (3 handlers)
7+
[GIN-debug] Loaded HTML Templates (4):
8+
- index.html
9+
-
10+
- footer.html
11+
- header.html
12+
13+
[GIN-debug] GET /api/videos --> main.main.func1 (3 handlers)
14+
[GIN-debug] POST /api/videos --> main.main.func2 (3 handlers)
15+
[GIN-debug] GET /view/videos --> gitlab.com/pragmaticreviews/golang-gin-poc/controller.VideoController.ShowAll-fm (3 handlers)
16+
[GIN-debug] [WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.
17+
Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.
18+
[GIN-debug] Listening and serving HTTP on :8080
19+
::1 - [29 Jan 22 01:30 +03] POST /api/videos 200 1.0623ms
20+
::1 - [29 Jan 22 01:30 +03] GET /view/videos 200 1.3972ms
21+
::1 - [29 Jan 22 01:30 +03] GET /favicon.ico 404 0s

go.mod

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
module gitlab.com/pragmaticreviews/golang-gin-poc
2+
3+
go 1.17
4+
5+
require (
6+
github.com/gin-contrib/sse v0.1.0 // indirect
7+
github.com/gin-gonic/gin v1.7.7 // indirect
8+
github.com/go-playground/locales v0.13.0 // indirect
9+
github.com/go-playground/universal-translator v0.17.0 // indirect
10+
github.com/go-playground/validator/v10 v10.4.1 // indirect
11+
github.com/golang/protobuf v1.3.3 // indirect
12+
github.com/json-iterator/go v1.1.9 // indirect
13+
github.com/leodido/go-urn v1.2.0 // indirect
14+
github.com/mattn/go-isatty v0.0.12 // indirect
15+
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
16+
github.com/modern-go/reflect2 v1.0.1 // indirect
17+
github.com/tpkeeper/gin-dump v1.0.1 // indirect
18+
github.com/ugorji/go/codec v1.1.7 // indirect
19+
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 // indirect
20+
golang.org/x/sys v0.0.0-20200116001909-b77594299b42 // indirect
21+
gopkg.in/yaml.v2 v2.2.8 // indirect
22+
)

go.sum

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
2+
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
3+
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
4+
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
5+
github.com/gin-gonic/gin v1.7.0/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY=
6+
github.com/gin-gonic/gin v1.7.7 h1:3DoBmSbJbZAWqXJC3SLjAPfutPJJRN1U5pALB7EeTTs=
7+
github.com/gin-gonic/gin v1.7.7/go.mod h1:axIBovoeJpVj8S3BwE0uPMTeReE4+AfFtqpqaZ1qq1U=
8+
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
9+
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
10+
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
11+
github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
12+
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
13+
github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE=
14+
github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
15+
github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I=
16+
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
17+
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
18+
github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns=
19+
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
20+
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
21+
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
22+
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
23+
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
24+
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
25+
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
26+
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
27+
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
28+
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg=
29+
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
30+
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
31+
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
32+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
33+
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
34+
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
35+
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
36+
github.com/tpkeeper/gin-dump v1.0.1 h1:H5vjXXNk/Yu/7EdNe5q4SaeQeOCYMue249+vbKdIjpY=
37+
github.com/tpkeeper/gin-dump v1.0.1/go.mod h1:+ar+0VEGsV3ogB27OFE41dRkYzPky24zMgSVeEnTJ/U=
38+
github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
39+
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
40+
github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
41+
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
42+
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
43+
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
44+
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
45+
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
46+
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
47+
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
48+
golang.org/x/sys v0.0.0-20200116001909-b77594299b42 h1:vEOn+mP2zCOVzKckCZy6YsCtDblrpj/w7B9nxGNELpg=
49+
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
50+
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
51+
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
52+
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
53+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
54+
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
55+
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
56+
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

middlewares/basic-auth.go

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package middlewares
2+
3+
import "github.com/gin-gonic/gin"
4+
5+
func BasicAuth() gin.HandlerFunc {
6+
return gin.BasicAuth(gin.Accounts{
7+
"sametavcii": "golang",
8+
})
9+
}

middlewares/logger.go

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package middlewares
2+
3+
import (
4+
"fmt"
5+
"time"
6+
7+
"github.com/gin-gonic/gin"
8+
)
9+
10+
func Logger() gin.HandlerFunc {
11+
return gin.LoggerWithFormatter(func(param gin.LogFormatterParams) string {
12+
return fmt.Sprintf("%s - [%s] %s %s %d %s \n",
13+
param.ClientIP,
14+
param.TimeStamp.Format(time.RFC822),
15+
param.Method,
16+
param.Path,
17+
param.StatusCode,
18+
param.Latency,
19+
)
20+
})
21+
}

server.go

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package main
2+
3+
import (
4+
"io"
5+
"net/http"
6+
"os"
7+
8+
"github.com/gin-gonic/gin"
9+
"gitlab.com/pragmaticreviews/golang-gin-poc/controller"
10+
"gitlab.com/pragmaticreviews/golang-gin-poc/middlewares"
11+
"gitlab.com/pragmaticreviews/golang-gin-poc/service"
12+
)
13+
14+
var (
15+
videoService service.VideoService = service.New()
16+
videoController controller.VideoController = controller.New(videoService)
17+
)
18+
19+
func setupLogOutput() {
20+
f, _ := os.Create("gin.log")
21+
gin.DefaultWriter = io.MultiWriter(f, os.Stdout)
22+
}
23+
24+
func main() {
25+
26+
setupLogOutput()
27+
28+
server := gin.New()
29+
30+
server.Use(gin.Recovery(), middlewares.Logger())
31+
32+
server.Static("/css", "./templates/css")
33+
34+
server.LoadHTMLGlob("templates/*.html")
35+
36+
apiRoutes := server.Group("/api")
37+
{
38+
apiRoutes.GET("/videos", func(ctx *gin.Context) {
39+
ctx.JSON(200, videoController.FindAll())
40+
})
41+
42+
apiRoutes.POST("/videos", func(ctx *gin.Context) {
43+
err := videoController.Save(ctx)
44+
if err != nil {
45+
ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
46+
} else {
47+
ctx.JSON(http.StatusOK, gin.H{"message": "Video Input is Valid!!"})
48+
}
49+
50+
})
51+
}
52+
viewRoutes := server.Group("/view")
53+
{
54+
viewRoutes.GET("/videos", videoController.ShowAll)
55+
}
56+
server.Run(":8080")
57+
}

service/service.go

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package service
2+
3+
import "gitlab.com/pragmaticreviews/golang-gin-poc/entity"
4+
5+
type VideoService interface {
6+
Save(entity.Video) entity.Video
7+
FindAll() []entity.Video
8+
}
9+
10+
type videoService struct {
11+
videos []entity.Video
12+
}
13+
14+
func New() VideoService {
15+
return &videoService{
16+
videos: []entity.Video{},
17+
}
18+
}
19+
20+
func (service *videoService) Save(video entity.Video) entity.Video {
21+
service.videos = append(service.videos, video)
22+
return video
23+
}
24+
25+
func (service *videoService) FindAll() []entity.Video {
26+
return service.videos
27+
}

templates/css/index.css

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
p {
2+
font-family: Arial, Helvetica, sans-serif;
3+
font-size: 1em;
4+
color: #606060;
5+
}

templates/footer.html

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
</body>
3+
4+
</html>

templates/header.html

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
2+
<!doctype html>
3+
<html>
4+
5+
<head>
6+
<title>{{ .title }}</title>
7+
<meta name="viewport" content="width=device-width, initial-scale=1">
8+
<meta charset="UTF-8">
9+
10+
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
11+
<link rel="stylesheet" href="/css/index.css" />
12+
</head>
13+
14+
<body class="container">

0 commit comments

Comments
 (0)