├── .idea ├── .gitignore ├── code.iml ├── modules.xml └── vcs.xml ├── README.md ├── config └── database.go ├── controller └── tag_controller.go ├── data ├── request │ ├── create_tags_request.go │ └── update_tags_request.go └── response │ ├── tags_reesponse.go │ └── web_response.go ├── docs ├── docs.go ├── swagger.json └── swagger.yaml ├── go.mod ├── go.sum ├── helper └── error.go ├── main.go ├── model └── tags.go ├── repository ├── tags_repository.go └── tags_repository_impl.go ├── router └── router.go └── service ├── tags_service.go └── tags_service_impl.go /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | -------------------------------------------------------------------------------- /.idea/code.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Build a RESTful CRUD API with Golang Gin and Gorm 2 | 3 | Building a RESTful CRUD (Create, Read, Update, Delete) API with Golang, Gin, and Gorm is a straightforward process. Gin is a popular web framework for building APIs in Golang, and Gorm is an ORM (Object-Relational Mapping) library for working with databases in Golang. Together, these two libraries make it easy to build a robust and efficient CRUD API. 4 | 5 | -------------------------------------------------------------------------------- /config/database.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import ( 4 | "fmt" 5 | "golang-crud-gin/helper" 6 | 7 | "gorm.io/driver/postgres" 8 | "gorm.io/gorm" 9 | ) 10 | 11 | const ( 12 | host = "localhost" 13 | port = 5432 14 | user = "postgres" 15 | password = "postgres" 16 | dbName = "test" 17 | ) 18 | 19 | func DatabaseConnection() *gorm.DB { 20 | sqlInfo := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=disable", host, port, user, password, dbName) 21 | db, err := gorm.Open(postgres.Open(sqlInfo), &gorm.Config{}) 22 | helper.ErrorPanic(err) 23 | 24 | return db 25 | } 26 | -------------------------------------------------------------------------------- /controller/tag_controller.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "golang-crud-gin/data/request" 5 | "golang-crud-gin/data/response" 6 | "golang-crud-gin/helper" 7 | "golang-crud-gin/service" 8 | "net/http" 9 | "strconv" 10 | 11 | "github.com/gin-gonic/gin" 12 | "github.com/rs/zerolog/log" 13 | ) 14 | 15 | type TagsController struct { 16 | tagsService service.TagsService 17 | } 18 | 19 | func NewTagsController(service service.TagsService) *TagsController { 20 | return &TagsController{ 21 | tagsService: service, 22 | } 23 | } 24 | 25 | // CreateTags godoc 26 | // @Summary Create tags 27 | // @Description Save tags data in Db. 28 | // @Param tags body request.CreateTagsRequest true "Create tags" 29 | // @Produce application/json 30 | // @Tags tags 31 | // @Success 200 {object} response.Response{} 32 | // @Router /tags [post] 33 | func (controller *TagsController) Create(ctx *gin.Context) { 34 | log.Info().Msg("create tags") 35 | createTagsRequest := request.CreateTagsRequest{} 36 | err := ctx.ShouldBindJSON(&createTagsRequest) 37 | helper.ErrorPanic(err) 38 | 39 | controller.tagsService.Create(createTagsRequest) 40 | webResponse := response.Response{ 41 | Code: http.StatusOK, 42 | Status: "Ok", 43 | Data: nil, 44 | } 45 | ctx.Header("Content-Type", "application/json") 46 | ctx.JSON(http.StatusOK, webResponse) 47 | } 48 | 49 | // UpdateTags godoc 50 | // @Summary Update tags 51 | // @Description Update tags data. 52 | // @Param tagId path string true "update tags by id" 53 | // @Param tags body request.CreateTagsRequest true "Update tags" 54 | // @Tags tags 55 | // @Produce application/json 56 | // @Success 200 {object} response.Response{} 57 | // @Router /tags/{tagId} [patch] 58 | func (controller *TagsController) Update(ctx *gin.Context) { 59 | log.Info().Msg("update tags") 60 | updateTagsRequest := request.UpdateTagsRequest{} 61 | err := ctx.ShouldBindJSON(&updateTagsRequest) 62 | helper.ErrorPanic(err) 63 | 64 | tagId := ctx.Param("tagId") 65 | id, err := strconv.Atoi(tagId) 66 | helper.ErrorPanic(err) 67 | updateTagsRequest.Id = id 68 | 69 | controller.tagsService.Update(updateTagsRequest) 70 | 71 | webResponse := response.Response{ 72 | Code: http.StatusOK, 73 | Status: "Ok", 74 | Data: nil, 75 | } 76 | ctx.Header("Content-Type", "application/json") 77 | ctx.JSON(http.StatusOK, webResponse) 78 | } 79 | 80 | // DeleteTags godoc 81 | // @Summary Delete tags 82 | // @Description Remove tags data by id. 83 | // @Produce application/json 84 | // @Tags tags 85 | // @Success 200 {object} response.Response{} 86 | // @Router /tags/{tagID} [delete] 87 | func (controller *TagsController) Delete(ctx *gin.Context) { 88 | log.Info().Msg("delete tags") 89 | tagId := ctx.Param("tagId") 90 | id, err := strconv.Atoi(tagId) 91 | helper.ErrorPanic(err) 92 | controller.tagsService.Delete(id) 93 | 94 | webResponse := response.Response{ 95 | Code: http.StatusOK, 96 | Status: "Ok", 97 | Data: nil, 98 | } 99 | ctx.Header("Content-Type", "application/json") 100 | ctx.JSON(http.StatusOK, webResponse) 101 | } 102 | 103 | // FindByIdTags godoc 104 | // @Summary Get Single tags by id. 105 | // @Param tagId path string true "update tags by id" 106 | // @Description Return the tahs whoes tagId valu mathes id. 107 | // @Produce application/json 108 | // @Tags tags 109 | // @Success 200 {object} response.Response{} 110 | // @Router /tags/{tagId} [get] 111 | func (controller *TagsController) FindById(ctx *gin.Context) { 112 | log.Info().Msg("findbyid tags") 113 | tagId := ctx.Param("tagId") 114 | id, err := strconv.Atoi(tagId) 115 | helper.ErrorPanic(err) 116 | 117 | tagResponse := controller.tagsService.FindById(id) 118 | 119 | webResponse := response.Response{ 120 | Code: http.StatusOK, 121 | Status: "Ok", 122 | Data: tagResponse, 123 | } 124 | ctx.Header("Content-Type", "application/json") 125 | ctx.JSON(http.StatusOK, webResponse) 126 | } 127 | 128 | // FindAllTags godoc 129 | // @Summary Get All tags. 130 | // @Description Return list of tags. 131 | // @Tags tags 132 | // @Success 200 {obejct} response.Response{} 133 | // @Router /tags [get] 134 | func (controller *TagsController) FindAll(ctx *gin.Context) { 135 | log.Info().Msg("findAll tags") 136 | tagResponse := controller.tagsService.FindAll() 137 | webResponse := response.Response{ 138 | Code: http.StatusOK, 139 | Status: "Ok", 140 | Data: tagResponse, 141 | } 142 | ctx.Header("Content-Type", "application/json") 143 | ctx.JSON(http.StatusOK, webResponse) 144 | 145 | } 146 | -------------------------------------------------------------------------------- /data/request/create_tags_request.go: -------------------------------------------------------------------------------- 1 | package request 2 | 3 | type CreateTagsRequest struct { 4 | Name string `validate:"required,min=1,max=200" json:"name"` 5 | } 6 | -------------------------------------------------------------------------------- /data/request/update_tags_request.go: -------------------------------------------------------------------------------- 1 | package request 2 | 3 | type UpdateTagsRequest struct { 4 | Id int `validate:"required"` 5 | Name string `validate:"required,max=200,min=1" json:"name"` 6 | } 7 | -------------------------------------------------------------------------------- /data/response/tags_reesponse.go: -------------------------------------------------------------------------------- 1 | package response 2 | 3 | type TagsResponse struct { 4 | Id int `json:"id"` 5 | Name string `json:"name"` 6 | } 7 | -------------------------------------------------------------------------------- /data/response/web_response.go: -------------------------------------------------------------------------------- 1 | package response 2 | 3 | type Response struct { 4 | Code int `json:"code"` 5 | Status string `json:"status"` 6 | Data interface{} `json:"data,omitempty"` 7 | } 8 | -------------------------------------------------------------------------------- /docs/docs.go: -------------------------------------------------------------------------------- 1 | // Package docs GENERATED BY SWAG; DO NOT EDIT 2 | // This file was generated by swaggo/swag 3 | package docs 4 | 5 | import "github.com/swaggo/swag" 6 | 7 | const docTemplate = `{ 8 | "schemes": {{ marshal .Schemes }}, 9 | "swagger": "2.0", 10 | "info": { 11 | "description": "{{escape .Description}}", 12 | "title": "{{.Title}}", 13 | "contact": {}, 14 | "version": "{{.Version}}" 15 | }, 16 | "host": "{{.Host}}", 17 | "basePath": "{{.BasePath}}", 18 | "paths": { 19 | "/tags": { 20 | "get": { 21 | "description": "Return list of tags.", 22 | "tags": [ 23 | "tags" 24 | ], 25 | "summary": "Get All tags.", 26 | "responses": { 27 | "200": { 28 | "description": "OK", 29 | "schema": { 30 | "type": "obejct" 31 | } 32 | } 33 | } 34 | }, 35 | "post": { 36 | "description": "Save tags data in Db.", 37 | "produces": [ 38 | "application/json" 39 | ], 40 | "tags": [ 41 | "tags" 42 | ], 43 | "summary": "Create tags", 44 | "parameters": [ 45 | { 46 | "description": "Create tags", 47 | "name": "tags", 48 | "in": "body", 49 | "required": true, 50 | "schema": { 51 | "$ref": "#/definitions/request.CreateTagsRequest" 52 | } 53 | } 54 | ], 55 | "responses": { 56 | "200": { 57 | "description": "OK", 58 | "schema": { 59 | "$ref": "#/definitions/response.Response" 60 | } 61 | } 62 | } 63 | } 64 | }, 65 | "/tags/{tagID}": { 66 | "delete": { 67 | "description": "Remove tags data by id.", 68 | "produces": [ 69 | "application/json" 70 | ], 71 | "tags": [ 72 | "tags" 73 | ], 74 | "summary": "Delete tags", 75 | "responses": { 76 | "200": { 77 | "description": "OK", 78 | "schema": { 79 | "$ref": "#/definitions/response.Response" 80 | } 81 | } 82 | } 83 | } 84 | }, 85 | "/tags/{tagId}": { 86 | "get": { 87 | "description": "Return the tahs whoes tagId valu mathes id.", 88 | "produces": [ 89 | "application/json" 90 | ], 91 | "tags": [ 92 | "tags" 93 | ], 94 | "summary": "Get Single tags by id.", 95 | "parameters": [ 96 | { 97 | "type": "string", 98 | "description": "update tags by id", 99 | "name": "tagId", 100 | "in": "path", 101 | "required": true 102 | } 103 | ], 104 | "responses": { 105 | "200": { 106 | "description": "OK", 107 | "schema": { 108 | "$ref": "#/definitions/response.Response" 109 | } 110 | } 111 | } 112 | }, 113 | "patch": { 114 | "description": "Update tags data.", 115 | "produces": [ 116 | "application/json" 117 | ], 118 | "tags": [ 119 | "tags" 120 | ], 121 | "summary": "Update tags", 122 | "parameters": [ 123 | { 124 | "type": "string", 125 | "description": "update tags by id", 126 | "name": "tagId", 127 | "in": "path", 128 | "required": true 129 | }, 130 | { 131 | "description": "Update tags", 132 | "name": "tags", 133 | "in": "body", 134 | "required": true, 135 | "schema": { 136 | "$ref": "#/definitions/request.CreateTagsRequest" 137 | } 138 | } 139 | ], 140 | "responses": { 141 | "200": { 142 | "description": "OK", 143 | "schema": { 144 | "$ref": "#/definitions/response.Response" 145 | } 146 | } 147 | } 148 | } 149 | } 150 | }, 151 | "definitions": { 152 | "request.CreateTagsRequest": { 153 | "type": "object", 154 | "required": [ 155 | "name" 156 | ], 157 | "properties": { 158 | "name": { 159 | "type": "string", 160 | "maxLength": 200, 161 | "minLength": 1 162 | } 163 | } 164 | }, 165 | "response.Response": { 166 | "type": "object", 167 | "properties": { 168 | "code": { 169 | "type": "integer" 170 | }, 171 | "data": {}, 172 | "status": { 173 | "type": "string" 174 | } 175 | } 176 | } 177 | } 178 | }` 179 | 180 | // SwaggerInfo holds exported Swagger Info so clients can modify it 181 | var SwaggerInfo = &swag.Spec{ 182 | Version: "1.0", 183 | Host: "localhost:8888", 184 | BasePath: "/api", 185 | Schemes: []string{}, 186 | Title: "Tag Service API", 187 | Description: "A Tag service API in Go using Gin framework", 188 | InfoInstanceName: "swagger", 189 | SwaggerTemplate: docTemplate, 190 | } 191 | 192 | func init() { 193 | swag.Register(SwaggerInfo.InstanceName(), SwaggerInfo) 194 | } 195 | -------------------------------------------------------------------------------- /docs/swagger.json: -------------------------------------------------------------------------------- 1 | { 2 | "swagger": "2.0", 3 | "info": { 4 | "description": "A Tag service API in Go using Gin framework", 5 | "title": "Tag Service API", 6 | "contact": {}, 7 | "version": "1.0" 8 | }, 9 | "host": "localhost:8888", 10 | "basePath": "/api", 11 | "paths": { 12 | "/tags": { 13 | "get": { 14 | "description": "Return list of tags.", 15 | "tags": [ 16 | "tags" 17 | ], 18 | "summary": "Get All tags.", 19 | "responses": { 20 | "200": { 21 | "description": "OK", 22 | "schema": { 23 | "type": "obejct" 24 | } 25 | } 26 | } 27 | }, 28 | "post": { 29 | "description": "Save tags data in Db.", 30 | "produces": [ 31 | "application/json" 32 | ], 33 | "tags": [ 34 | "tags" 35 | ], 36 | "summary": "Create tags", 37 | "parameters": [ 38 | { 39 | "description": "Create tags", 40 | "name": "tags", 41 | "in": "body", 42 | "required": true, 43 | "schema": { 44 | "$ref": "#/definitions/request.CreateTagsRequest" 45 | } 46 | } 47 | ], 48 | "responses": { 49 | "200": { 50 | "description": "OK", 51 | "schema": { 52 | "$ref": "#/definitions/response.Response" 53 | } 54 | } 55 | } 56 | } 57 | }, 58 | "/tags/{tagID}": { 59 | "delete": { 60 | "description": "Remove tags data by id.", 61 | "produces": [ 62 | "application/json" 63 | ], 64 | "tags": [ 65 | "tags" 66 | ], 67 | "summary": "Delete tags", 68 | "responses": { 69 | "200": { 70 | "description": "OK", 71 | "schema": { 72 | "$ref": "#/definitions/response.Response" 73 | } 74 | } 75 | } 76 | } 77 | }, 78 | "/tags/{tagId}": { 79 | "get": { 80 | "description": "Return the tahs whoes tagId valu mathes id.", 81 | "produces": [ 82 | "application/json" 83 | ], 84 | "tags": [ 85 | "tags" 86 | ], 87 | "summary": "Get Single tags by id.", 88 | "parameters": [ 89 | { 90 | "type": "string", 91 | "description": "update tags by id", 92 | "name": "tagId", 93 | "in": "path", 94 | "required": true 95 | } 96 | ], 97 | "responses": { 98 | "200": { 99 | "description": "OK", 100 | "schema": { 101 | "$ref": "#/definitions/response.Response" 102 | } 103 | } 104 | } 105 | }, 106 | "patch": { 107 | "description": "Update tags data.", 108 | "produces": [ 109 | "application/json" 110 | ], 111 | "tags": [ 112 | "tags" 113 | ], 114 | "summary": "Update tags", 115 | "parameters": [ 116 | { 117 | "type": "string", 118 | "description": "update tags by id", 119 | "name": "tagId", 120 | "in": "path", 121 | "required": true 122 | }, 123 | { 124 | "description": "Update tags", 125 | "name": "tags", 126 | "in": "body", 127 | "required": true, 128 | "schema": { 129 | "$ref": "#/definitions/request.CreateTagsRequest" 130 | } 131 | } 132 | ], 133 | "responses": { 134 | "200": { 135 | "description": "OK", 136 | "schema": { 137 | "$ref": "#/definitions/response.Response" 138 | } 139 | } 140 | } 141 | } 142 | } 143 | }, 144 | "definitions": { 145 | "request.CreateTagsRequest": { 146 | "type": "object", 147 | "required": [ 148 | "name" 149 | ], 150 | "properties": { 151 | "name": { 152 | "type": "string", 153 | "maxLength": 200, 154 | "minLength": 1 155 | } 156 | } 157 | }, 158 | "response.Response": { 159 | "type": "object", 160 | "properties": { 161 | "code": { 162 | "type": "integer" 163 | }, 164 | "data": {}, 165 | "status": { 166 | "type": "string" 167 | } 168 | } 169 | } 170 | } 171 | } -------------------------------------------------------------------------------- /docs/swagger.yaml: -------------------------------------------------------------------------------- 1 | basePath: /api 2 | definitions: 3 | request.CreateTagsRequest: 4 | properties: 5 | name: 6 | maxLength: 200 7 | minLength: 1 8 | type: string 9 | required: 10 | - name 11 | type: object 12 | response.Response: 13 | properties: 14 | code: 15 | type: integer 16 | data: {} 17 | status: 18 | type: string 19 | type: object 20 | host: localhost:8888 21 | info: 22 | contact: {} 23 | description: A Tag service API in Go using Gin framework 24 | title: Tag Service API 25 | version: "1.0" 26 | paths: 27 | /tags: 28 | get: 29 | description: Return list of tags. 30 | responses: 31 | "200": 32 | description: OK 33 | schema: 34 | type: obejct 35 | summary: Get All tags. 36 | tags: 37 | - tags 38 | post: 39 | description: Save tags data in Db. 40 | parameters: 41 | - description: Create tags 42 | in: body 43 | name: tags 44 | required: true 45 | schema: 46 | $ref: '#/definitions/request.CreateTagsRequest' 47 | produces: 48 | - application/json 49 | responses: 50 | "200": 51 | description: OK 52 | schema: 53 | $ref: '#/definitions/response.Response' 54 | summary: Create tags 55 | tags: 56 | - tags 57 | /tags/{tagID}: 58 | delete: 59 | description: Remove tags data by id. 60 | produces: 61 | - application/json 62 | responses: 63 | "200": 64 | description: OK 65 | schema: 66 | $ref: '#/definitions/response.Response' 67 | summary: Delete tags 68 | tags: 69 | - tags 70 | /tags/{tagId}: 71 | get: 72 | description: Return the tahs whoes tagId valu mathes id. 73 | parameters: 74 | - description: update tags by id 75 | in: path 76 | name: tagId 77 | required: true 78 | type: string 79 | produces: 80 | - application/json 81 | responses: 82 | "200": 83 | description: OK 84 | schema: 85 | $ref: '#/definitions/response.Response' 86 | summary: Get Single tags by id. 87 | tags: 88 | - tags 89 | patch: 90 | description: Update tags data. 91 | parameters: 92 | - description: update tags by id 93 | in: path 94 | name: tagId 95 | required: true 96 | type: string 97 | - description: Update tags 98 | in: body 99 | name: tags 100 | required: true 101 | schema: 102 | $ref: '#/definitions/request.CreateTagsRequest' 103 | produces: 104 | - application/json 105 | responses: 106 | "200": 107 | description: OK 108 | schema: 109 | $ref: '#/definitions/response.Response' 110 | summary: Update tags 111 | tags: 112 | - tags 113 | swagger: "2.0" 114 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module golang-crud-gin 2 | 3 | go 1.19 4 | 5 | require ( 6 | github.com/KyleBanks/depth v1.2.1 // indirect 7 | github.com/PuerkitoBio/purell v1.2.0 // indirect 8 | github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect 9 | github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect 10 | github.com/ghodss/yaml v1.0.0 // indirect 11 | github.com/gin-contrib/sse v0.1.0 // indirect 12 | github.com/gin-gonic/gin v1.8.2 // indirect 13 | github.com/go-openapi/jsonpointer v0.19.6 // indirect 14 | github.com/go-openapi/jsonreference v0.20.1 // indirect 15 | github.com/go-openapi/spec v0.20.7 // indirect 16 | github.com/go-openapi/swag v0.22.3 // indirect 17 | github.com/go-playground/locales v0.14.1 // indirect 18 | github.com/go-playground/universal-translator v0.18.0 // indirect 19 | github.com/go-playground/validator/v10 v10.11.1 // indirect 20 | github.com/goccy/go-json v0.10.0 // indirect 21 | github.com/jackc/pgpassfile v1.0.0 // indirect 22 | github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect 23 | github.com/jackc/pgx/v5 v5.2.0 // indirect 24 | github.com/jinzhu/inflection v1.0.0 // indirect 25 | github.com/jinzhu/now v1.1.5 // indirect 26 | github.com/josharian/intern v1.0.0 // indirect 27 | github.com/json-iterator/go v1.1.12 // indirect 28 | github.com/leodido/go-urn v1.2.1 // indirect 29 | github.com/mailru/easyjson v0.7.7 // indirect 30 | github.com/mattn/go-colorable v0.1.12 // indirect 31 | github.com/mattn/go-isatty v0.0.17 // indirect 32 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 33 | github.com/modern-go/reflect2 v1.0.2 // indirect 34 | github.com/pelletier/go-toml/v2 v2.0.6 // indirect 35 | github.com/rs/zerolog v1.28.0 // indirect 36 | github.com/russross/blackfriday/v2 v2.1.0 // indirect 37 | github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect 38 | github.com/swaggo/files v1.0.0 // indirect 39 | github.com/swaggo/gin-swagger v1.5.3 // indirect 40 | github.com/swaggo/swag v1.8.9 // indirect 41 | github.com/ugorji/go/codec v1.2.8 // indirect 42 | github.com/urfave/cli/v2 v2.23.7 // indirect 43 | github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect 44 | golang.org/x/crypto v0.5.0 // indirect 45 | golang.org/x/net v0.5.0 // indirect 46 | golang.org/x/sys v0.4.0 // indirect 47 | golang.org/x/text v0.6.0 // indirect 48 | golang.org/x/tools v0.5.0 // indirect 49 | google.golang.org/protobuf v1.28.1 // indirect 50 | gopkg.in/yaml.v2 v2.4.0 // indirect 51 | gopkg.in/yaml.v3 v3.0.1 // indirect 52 | gorm.io/driver/postgres v1.4.6 // indirect 53 | gorm.io/gorm v1.24.3 // indirect 54 | ) 55 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= 2 | github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc= 3 | github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= 4 | github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= 5 | github.com/PuerkitoBio/purell v1.2.0 h1:/Jdm5QfyM8zdlqT6WVZU4cfP23sot6CEHA4CS49Ezig= 6 | github.com/PuerkitoBio/purell v1.2.0/go.mod h1:OhLRTaaIzhvIyofkJfB24gokC7tM42Px5UhoT32THBk= 7 | github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= 8 | github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= 9 | github.com/agiledragon/gomonkey/v2 v2.3.1/go.mod h1:ap1AmDzcVOAz1YpeJ3TCzIgstoaWLA6jbbgxfB4w2iY= 10 | github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= 11 | github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= 12 | github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= 13 | github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= 14 | github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= 15 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 16 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 17 | github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= 18 | github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= 19 | github.com/gin-contrib/gzip v0.0.6/go.mod h1:QOJlmV2xmayAjkNS2Y8NQsMneuRShOU/kjovCXNuzzk= 20 | github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= 21 | github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= 22 | github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk= 23 | github.com/gin-gonic/gin v1.8.2 h1:UzKToD9/PoFj/V4rvlKqTRKnQYyz8Sc1MJlv4JHPtvY= 24 | github.com/gin-gonic/gin v1.8.2/go.mod h1:qw5AYuDrzRTnhvusDsrov+fDIxp9Dleuu12h8nfB398= 25 | github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= 26 | github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= 27 | github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= 28 | github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= 29 | github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns= 30 | github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo= 31 | github.com/go-openapi/jsonreference v0.20.1 h1:FBLnyygC4/IZZr893oiomc9XaghoveYTrLC1F86HID8= 32 | github.com/go-openapi/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= 33 | github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I= 34 | github.com/go-openapi/spec v0.20.7 h1:1Rlu/ZrOCCob0n+JKKJAWhNWMPW8bOZRg8FJaY+0SKI= 35 | github.com/go-openapi/spec v0.20.7/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA= 36 | github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= 37 | github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= 38 | github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= 39 | github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= 40 | github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= 41 | github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= 42 | github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= 43 | github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= 44 | github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= 45 | github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= 46 | github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= 47 | github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos= 48 | github.com/go-playground/validator/v10 v10.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJWXmqUsHwfTRRkQ= 49 | github.com/go-playground/validator/v10 v10.11.1/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU= 50 | github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= 51 | github.com/goccy/go-json v0.9.11 h1:/pAaQDLHEoCq/5FFmSKBswWmK6H0e8g4159Kc/X/nqk= 52 | github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= 53 | github.com/goccy/go-json v0.10.0 h1:mXKd9Qw4NuzShiRlOXKews24ufknHO7gx30lsDyokKA= 54 | github.com/goccy/go-json v0.10.0/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= 55 | github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= 56 | github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= 57 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 58 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 59 | github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= 60 | github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= 61 | github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= 62 | github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= 63 | github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk= 64 | github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= 65 | github.com/jackc/pgx/v5 v5.2.0 h1:NdPpngX0Y6z6XDFKqmFQaE+bCtkqzvQIOt1wvBlAqs8= 66 | github.com/jackc/pgx/v5 v5.2.0/go.mod h1:Ptn7zmohNsWEsdxRawMzk3gaKma2obW+NWTnKa0S4nk= 67 | github.com/jackc/puddle/v2 v2.1.2/go.mod h1:2lpufsF5mRHO6SuZkm0fNYxM6SWHfvyFj62KwNzgels= 68 | github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= 69 | github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= 70 | github.com/jinzhu/now v1.1.4 h1:tHnRBy1i5F2Dh8BAFxqFzxKqqvezXrL2OW1TnX+Mlas= 71 | github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= 72 | github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= 73 | github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= 74 | github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= 75 | github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= 76 | github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= 77 | github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= 78 | github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= 79 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 80 | github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= 81 | github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= 82 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 83 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 84 | github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= 85 | github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= 86 | github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= 87 | github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= 88 | github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= 89 | github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= 90 | github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= 91 | github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= 92 | github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= 93 | github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= 94 | github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= 95 | github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= 96 | github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= 97 | github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= 98 | github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= 99 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= 100 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 101 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= 102 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 103 | github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= 104 | github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= 105 | github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= 106 | github.com/otiai10/copy v1.7.0/go.mod h1:rmRl6QPdJj6EiUqXQ/4Nn2lLXoNQjFCQbbNrxgc/t3U= 107 | github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= 108 | github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= 109 | github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= 110 | github.com/otiai10/mint v1.3.3/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= 111 | github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= 112 | github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU= 113 | github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek= 114 | github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= 115 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 116 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 117 | github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= 118 | github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= 119 | github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= 120 | github.com/rs/zerolog v1.28.0 h1:MirSo27VyNi7RJYP3078AA1+Cyzd2GB66qy3aUHvsWY= 121 | github.com/rs/zerolog v1.28.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0= 122 | github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= 123 | github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= 124 | github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= 125 | github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= 126 | github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= 127 | github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= 128 | github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= 129 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 130 | github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= 131 | github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= 132 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 133 | github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= 134 | github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 135 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 136 | github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 137 | github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= 138 | github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= 139 | github.com/swaggo/files v0.0.0-20220728132757-551d4a08d97a/go.mod h1:lKJPbtWzJ9JhsTN1k1gZgleJWY/cqq0psdoMmaThG3w= 140 | github.com/swaggo/files v1.0.0 h1:1gGXVIeUFCS/dta17rnP0iOpr6CXFwKD7EO5ID233e4= 141 | github.com/swaggo/files v1.0.0/go.mod h1:N59U6URJLyU1PQgFqPM7wXLMhJx7QAolnvfQkqO13kc= 142 | github.com/swaggo/gin-swagger v1.5.3 h1:8mWmHLolIbrhJJTflsaFoZzRBYVmEE7JZGIq08EiC0Q= 143 | github.com/swaggo/gin-swagger v1.5.3/go.mod h1:3XJKSfHjDMB5dBo/0rrTXidPmgLeqsX89Yp4uA50HpI= 144 | github.com/swaggo/swag v1.8.1/go.mod h1:ugemnJsPZm/kRwFUnzBlbHRd0JY9zE1M4F+uy2pAaPQ= 145 | github.com/swaggo/swag v1.8.9 h1:kHtaBe/Ob9AZzAANfcn5c6RyCke9gG9QpH0jky0I/sA= 146 | github.com/swaggo/swag v1.8.9/go.mod h1:ezQVUUhly8dludpVk+/PuwJWvLLanB13ygV5Pr9enSk= 147 | github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= 148 | github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= 149 | github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= 150 | github.com/ugorji/go/codec v1.2.8 h1:sgBJS6COt0b/P40VouWKdseidkDgHxYGm0SAglUHfP0= 151 | github.com/ugorji/go/codec v1.2.8/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= 152 | github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= 153 | github.com/urfave/cli/v2 v2.23.7 h1:YHDQ46s3VghFHFf1DdF+Sh7H4RqhcM+t0TmZRJx4oJY= 154 | github.com/urfave/cli/v2 v2.23.7/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc= 155 | github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= 156 | github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= 157 | github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= 158 | github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= 159 | go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= 160 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 161 | golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 162 | golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= 163 | golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= 164 | golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 h1:0es+/5331RGQPcXlMfP+WrnIIS6dNnNRe0WB02W0F4M= 165 | golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= 166 | golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= 167 | golang.org/x/crypto v0.4.0 h1:UVQgzMY87xqpKNgb+kDsll2Igd33HszWHFLmpaRMq/8= 168 | golang.org/x/crypto v0.4.0/go.mod h1:3quD/ATkf6oY+rnes5c3ExXTbLc8mueNue5/DoinL80= 169 | golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE= 170 | golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= 171 | golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 172 | golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= 173 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 174 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 175 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 176 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 177 | golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= 178 | golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 179 | golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 180 | golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= 181 | golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= 182 | golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= 183 | golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= 184 | golang.org/x/net v0.4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU= 185 | golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= 186 | golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw= 187 | golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= 188 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 189 | golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 190 | golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 191 | golang.org/x/sync v0.0.0-20220923202941-7f9b1623fab7/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 192 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 193 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 194 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 195 | golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 196 | golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 197 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 198 | golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 199 | golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 200 | golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 201 | golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 202 | golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 203 | golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 204 | golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 205 | golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 206 | golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 207 | golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ= 208 | golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 209 | golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18= 210 | golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 211 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 212 | golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= 213 | golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= 214 | golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= 215 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 216 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 217 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 218 | golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= 219 | golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= 220 | golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= 221 | golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM= 222 | golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= 223 | golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k= 224 | golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= 225 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 226 | golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 227 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 228 | golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= 229 | golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= 230 | golang.org/x/tools v0.5.0 h1:+bSpV5HIeWkuvgaMfI3UmKRThoTA5ODJTUd8T17NO+4= 231 | golang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k= 232 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 233 | golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 234 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 235 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 236 | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= 237 | google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= 238 | google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= 239 | google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= 240 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 241 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 242 | gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 243 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= 244 | gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= 245 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 246 | gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 247 | gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= 248 | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= 249 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 250 | gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 251 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 252 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 253 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 254 | gorm.io/driver/postgres v1.4.6 h1:1FPESNXqIKG5JmraaH2bfCVlMQ7paLoCreFxDtqzwdc= 255 | gorm.io/driver/postgres v1.4.6/go.mod h1:UJChCNLFKeBqQRE+HrkFUbKbq9idPXmTOk2u4Wok8S4= 256 | gorm.io/gorm v1.24.2/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA= 257 | gorm.io/gorm v1.24.3 h1:WL2ifUmzR/SLp85CSURAfybcHnGZ+yLSGSxgYXlFBHg= 258 | gorm.io/gorm v1.24.3/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA= 259 | -------------------------------------------------------------------------------- /helper/error.go: -------------------------------------------------------------------------------- 1 | package helper 2 | 3 | func ErrorPanic(err error) { 4 | if err != nil { 5 | panic(err) 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "golang-crud-gin/config" 5 | "golang-crud-gin/controller" 6 | _ "golang-crud-gin/docs" 7 | "golang-crud-gin/helper" 8 | "golang-crud-gin/model" 9 | "golang-crud-gin/repository" 10 | "golang-crud-gin/router" 11 | "golang-crud-gin/service" 12 | "net/http" 13 | 14 | "github.com/go-playground/validator/v10" 15 | "github.com/rs/zerolog/log" 16 | ) 17 | 18 | // @title Tag Service API 19 | // @version 1.0 20 | // @description A Tag service API in Go using Gin framework 21 | 22 | // @host localhost:8888 23 | // @BasePath /api 24 | func main() { 25 | 26 | log.Info().Msg("Started Server!") 27 | // Database 28 | db := config.DatabaseConnection() 29 | validate := validator.New() 30 | 31 | db.Table("tags").AutoMigrate(&model.Tags{}) 32 | 33 | // Repository 34 | tagsRepository := repository.NewTagsREpositoryImpl(db) 35 | 36 | // Service 37 | tagsService := service.NewTagsServiceImpl(tagsRepository, validate) 38 | 39 | // Controller 40 | tagsController := controller.NewTagsController(tagsService) 41 | 42 | // Router 43 | routes := router.NewRouter(tagsController) 44 | 45 | server := &http.Server{ 46 | Addr: ":8888", 47 | Handler: routes, 48 | } 49 | 50 | err := server.ListenAndServe() 51 | helper.ErrorPanic(err) 52 | } 53 | -------------------------------------------------------------------------------- /model/tags.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | type Tags struct { 4 | Id int `gorm:"type:int;primary_key"` 5 | Name string `gorm:"type:varchar(255)"` 6 | } 7 | -------------------------------------------------------------------------------- /repository/tags_repository.go: -------------------------------------------------------------------------------- 1 | package repository 2 | 3 | import "golang-crud-gin/model" 4 | 5 | type TagsRepository interface { 6 | Save(tags model.Tags) 7 | Update(tags model.Tags) 8 | Delete(tagsId int) 9 | FindById(tagsId int) (tags model.Tags, err error) 10 | FindAll() []model.Tags 11 | } 12 | -------------------------------------------------------------------------------- /repository/tags_repository_impl.go: -------------------------------------------------------------------------------- 1 | package repository 2 | 3 | import ( 4 | "errors" 5 | "golang-crud-gin/data/request" 6 | "golang-crud-gin/helper" 7 | "golang-crud-gin/model" 8 | 9 | "gorm.io/gorm" 10 | ) 11 | 12 | type TagsRepositoryImpl struct { 13 | Db *gorm.DB 14 | } 15 | 16 | func NewTagsREpositoryImpl(Db *gorm.DB) TagsRepository { 17 | return &TagsRepositoryImpl{Db: Db} 18 | } 19 | 20 | // Delete implements TagsRepository 21 | func (t *TagsRepositoryImpl) Delete(tagsId int) { 22 | var tags model.Tags 23 | result := t.Db.Where("id = ?", tagsId).Delete(&tags) 24 | helper.ErrorPanic(result.Error) 25 | } 26 | 27 | // FindAll implements TagsRepository 28 | func (t *TagsRepositoryImpl) FindAll() []model.Tags { 29 | var tags []model.Tags 30 | result := t.Db.Find(&tags) 31 | helper.ErrorPanic(result.Error) 32 | return tags 33 | } 34 | 35 | // FindById implements TagsRepository 36 | func (t *TagsRepositoryImpl) FindById(tagsId int) (tags model.Tags, err error) { 37 | var tag model.Tags 38 | result := t.Db.Find(&tag, tagsId) 39 | if result != nil { 40 | return tag, nil 41 | } else { 42 | return tag, errors.New("tag is not found") 43 | } 44 | } 45 | 46 | // Save implements TagsRepository 47 | func (t *TagsRepositoryImpl) Save(tags model.Tags) { 48 | result := t.Db.Create(&tags) 49 | helper.ErrorPanic(result.Error) 50 | } 51 | 52 | // Update implements TagsRepository 53 | func (t *TagsRepositoryImpl) Update(tags model.Tags) { 54 | var updateTag = request.UpdateTagsRequest{ 55 | Id: tags.Id, 56 | Name: tags.Name, 57 | } 58 | result := t.Db.Model(&tags).Updates(updateTag) 59 | helper.ErrorPanic(result.Error) 60 | } 61 | -------------------------------------------------------------------------------- /router/router.go: -------------------------------------------------------------------------------- 1 | package router 2 | 3 | import ( 4 | "golang-crud-gin/controller" 5 | 6 | "net/http" 7 | 8 | "github.com/gin-gonic/gin" 9 | swaggerFiles "github.com/swaggo/files" 10 | ginSwagger "github.com/swaggo/gin-swagger" 11 | ) 12 | 13 | func NewRouter(tagsController *controller.TagsController) *gin.Engine { 14 | router := gin.Default() 15 | // add swagger 16 | router.GET("/docs/*any", ginSwagger.WrapHandler(swaggerFiles.Handler)) 17 | 18 | router.GET("", func(ctx *gin.Context) { 19 | ctx.JSON(http.StatusOK, "welcome home") 20 | }) 21 | baseRouter := router.Group("/api") 22 | tagsRouter := baseRouter.Group("/tags") 23 | tagsRouter.GET("", tagsController.FindAll) 24 | tagsRouter.GET("/:tagId", tagsController.FindById) 25 | tagsRouter.POST("", tagsController.Create) 26 | tagsRouter.PATCH("/:tagId", tagsController.Update) 27 | tagsRouter.DELETE("/:tagId", tagsController.Delete) 28 | 29 | return router 30 | } 31 | -------------------------------------------------------------------------------- /service/tags_service.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "golang-crud-gin/data/request" 5 | "golang-crud-gin/data/response" 6 | ) 7 | 8 | type TagsService interface { 9 | Create(tags request.CreateTagsRequest) 10 | Update(tags request.UpdateTagsRequest) 11 | Delete(tagsId int) 12 | FindById(tagsId int) response.TagsResponse 13 | FindAll() []response.TagsResponse 14 | } 15 | -------------------------------------------------------------------------------- /service/tags_service_impl.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "golang-crud-gin/data/request" 5 | "golang-crud-gin/data/response" 6 | "golang-crud-gin/helper" 7 | "golang-crud-gin/model" 8 | "golang-crud-gin/repository" 9 | 10 | "github.com/go-playground/validator/v10" 11 | ) 12 | 13 | type TagsServiceImpl struct { 14 | TagsRepository repository.TagsRepository 15 | Validate *validator.Validate 16 | } 17 | 18 | func NewTagsServiceImpl(tagRepository repository.TagsRepository, validate *validator.Validate) TagsService { 19 | return &TagsServiceImpl{ 20 | TagsRepository: tagRepository, 21 | Validate: validate, 22 | } 23 | } 24 | 25 | // Create implements TagsService 26 | func (t *TagsServiceImpl) Create(tags request.CreateTagsRequest) { 27 | err := t.Validate.Struct(tags) 28 | helper.ErrorPanic(err) 29 | tagModel := model.Tags{ 30 | Name: tags.Name, 31 | } 32 | t.TagsRepository.Save(tagModel) 33 | } 34 | 35 | // Delete implements TagsService 36 | func (t *TagsServiceImpl) Delete(tagsId int) { 37 | t.TagsRepository.Delete(tagsId) 38 | } 39 | 40 | // FindAll implements TagsService 41 | func (t *TagsServiceImpl) FindAll() []response.TagsResponse { 42 | result := t.TagsRepository.FindAll() 43 | 44 | var tags []response.TagsResponse 45 | for _, value := range result { 46 | tag := response.TagsResponse{ 47 | Id: value.Id, 48 | Name: value.Name, 49 | } 50 | tags = append(tags, tag) 51 | } 52 | 53 | return tags 54 | } 55 | 56 | // FindById implements TagsService 57 | func (t *TagsServiceImpl) FindById(tagsId int) response.TagsResponse { 58 | tagData, err := t.TagsRepository.FindById(tagsId) 59 | helper.ErrorPanic(err) 60 | 61 | tagResponse := response.TagsResponse{ 62 | Id: tagData.Id, 63 | Name: tagData.Name, 64 | } 65 | return tagResponse 66 | } 67 | 68 | // Update implements TagsService 69 | func (t *TagsServiceImpl) Update(tags request.UpdateTagsRequest) { 70 | tagData, err := t.TagsRepository.FindById(tags.Id) 71 | helper.ErrorPanic(err) 72 | tagData.Name = tags.Name 73 | t.TagsRepository.Update(tagData) 74 | } 75 | --------------------------------------------------------------------------------