Skip to content

Commit 685e51b

Browse files
author
itsaadarsh
committed
Book route completed v1
1 parent 56b5282 commit 685e51b

File tree

7 files changed

+295
-10
lines changed

7 files changed

+295
-10
lines changed

Diff for: controller/book-controller.go

+149
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
package controller
2+
3+
import (
4+
"fmt"
5+
"gogin/dto"
6+
"gogin/entity"
7+
"gogin/helper"
8+
"gogin/service"
9+
"net/http"
10+
"strconv"
11+
12+
"github.com/gin-gonic/gin"
13+
"github.com/golang-jwt/jwt"
14+
)
15+
16+
type BookController interface {
17+
Insert(ctx *gin.Context)
18+
Update(ctx *gin.Context)
19+
Delete(ctx *gin.Context)
20+
All(ctx *gin.Context)
21+
FindByID(ctx *gin.Context)
22+
}
23+
24+
type bookController struct {
25+
bookService service.BookService
26+
jwtService service.JWTService
27+
}
28+
29+
func NewBookController(bookSer service.BookService, jwtSer service.JWTService) BookController {
30+
return &bookController{
31+
bookService: bookSer,
32+
jwtService: jwtSer,
33+
}
34+
}
35+
36+
func (c *bookController) getUserIDByToken(token string) string {
37+
aToken, errToken := c.jwtService.ValidateToken(token)
38+
if errToken != nil {
39+
panic(errToken.Error())
40+
}
41+
claims := aToken.Claims.(jwt.MapClaims)
42+
return fmt.Sprint("%v", claims["user_id"])
43+
}
44+
45+
func (c *bookController) Insert(ctx *gin.Context) {
46+
var bookInsertDTO dto.BookCreatedDTO
47+
errDTO := ctx.ShouldBind(&bookInsertDTO)
48+
if errDTO != nil {
49+
response := helper.BuildErrorResponse("Failed to process request", errDTO.Error(), helper.EmptyObj{})
50+
ctx.AbortWithStatusJSON(http.StatusBadRequest, response)
51+
return
52+
}
53+
authHeader := ctx.GetHeader("Authorization")
54+
userID := c.getUserIDByToken(authHeader)
55+
userIDUint, err := strconv.ParseUint(userID, 10, 64)
56+
if err == nil {
57+
bookInsertDTO.UserID = userIDUint
58+
}
59+
60+
bookInserted := c.bookService.Insert(bookInsertDTO)
61+
response := helper.BuildResponse(true, "OK", bookInserted)
62+
ctx.JSON(http.StatusOK, response)
63+
64+
}
65+
66+
func (c *bookController) Update(ctx *gin.Context) {
67+
var bookUpdateDTO dto.BookUpdateDTO
68+
errDTO := ctx.ShouldBind(&bookUpdateDTO)
69+
if errDTO != nil {
70+
response := helper.BuildErrorResponse("Failed to process request", errDTO.Error(), helper.EmptyObj{})
71+
ctx.AbortWithStatusJSON(http.StatusBadRequest, response)
72+
return
73+
}
74+
75+
authHeader := ctx.GetHeader("Authorization")
76+
token, errToken := c.jwtService.ValidateToken(authHeader)
77+
if errToken != nil {
78+
panic(errToken.Error())
79+
}
80+
81+
claims := token.Claims.(jwt.MapClaims)
82+
userId := fmt.Sprintf("%v", claims["user_id"])
83+
if c.bookService.IsAllowedToEdit(userId, bookUpdateDTO.ID) {
84+
id, errID := strconv.ParseUint(userId, 10, 64)
85+
if errID == nil {
86+
bookUpdateDTO.UserID = id
87+
}
88+
bookUpdated := c.bookService.Update(bookUpdateDTO)
89+
response := helper.BuildResponse(true, "OK", bookUpdated)
90+
ctx.JSON(http.StatusOK, response)
91+
} else {
92+
response := helper.BuildErrorResponse("You don't have permission", "Incorrect user ID", helper.EmptyObj{})
93+
ctx.AbortWithStatusJSON(http.StatusForbidden, response)
94+
}
95+
96+
}
97+
func (c *bookController) Delete(ctx *gin.Context) {
98+
var book entity.Book
99+
100+
id, err := strconv.ParseUint(ctx.Param("id"), 0, 0)
101+
if err != nil {
102+
response := helper.BuildErrorResponse("No param ID was found", err.Error(), helper.EmptyObj{})
103+
ctx.AbortWithStatusJSON(http.StatusBadRequest, response)
104+
return
105+
}
106+
107+
book.ID = id
108+
authHeader := ctx.GetHeader("Authorization")
109+
token, errToken := c.jwtService.ValidateToken(authHeader)
110+
if errToken != nil {
111+
panic(errToken.Error())
112+
}
113+
114+
claims := token.Claims.(jwt.MapClaims)
115+
userId := fmt.Sprintf("%v", claims["user_id"])
116+
if c.bookService.IsAllowedToEdit(userId, book.ID) {
117+
c.bookService.Delete(book)
118+
response := helper.BuildResponse(true, "OK", helper.EmptyObj{})
119+
ctx.JSON(http.StatusOK, response)
120+
} else {
121+
response := helper.BuildErrorResponse("You don't have permission", "Incorrect user ID", helper.EmptyObj{})
122+
ctx.AbortWithStatusJSON(http.StatusForbidden, response)
123+
}
124+
}
125+
126+
func (c *bookController) All(ctx *gin.Context) {
127+
var books []entity.Book = c.bookService.All()
128+
response := helper.BuildResponse(true, "OK", books)
129+
ctx.JSON(http.StatusOK, response)
130+
}
131+
132+
func (c *bookController) FindByID(ctx *gin.Context) {
133+
134+
bookUint, err := strconv.ParseUint(ctx.Param("id"), 0, 0)
135+
if err != nil {
136+
response := helper.BuildErrorResponse("No param ID was found", err.Error(), helper.EmptyObj{})
137+
ctx.AbortWithStatusJSON(http.StatusBadRequest, response)
138+
return
139+
}
140+
141+
bookRes := c.bookService.FindByID(bookUint)
142+
if (bookRes == entity.Book{}) {
143+
response := helper.BuildErrorResponse("Data Not Found", "No data found with the given ID", helper.EmptyObj{})
144+
ctx.AbortWithStatusJSON(http.StatusNotFound, response)
145+
} else {
146+
response := helper.BuildResponse(true, "OK", bookRes)
147+
ctx.JSON(http.StatusOK, response)
148+
}
149+
}

Diff for: controller/user-controller.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ func (c *userController) Update(ctx *gin.Context) {
4848
id, err := strconv.ParseUint(fmt.Sprintf("%v", claims["user_id"]), 10, 64)
4949

5050
if err != nil {
51-
panic(errToken.Error())
51+
panic(err.Error())
5252
}
5353

5454
userUpdateDTO.ID = id

Diff for: dto/book_dto.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ type BookUpdateDTO struct {
44
ID uint64 `json:"id" form:"id" binding:"required"`
55
Title string `json:"title" form:"title" binding:"required"`
66
Description string `json:"description" form:"description" binding:"required"`
7-
UserID string `json:"user_id,omitempty" form:"user_id,omitempty"`
7+
UserID uint64 `json:"user_id,omitempty" form:"user_id,omitempty"`
88
}
99

1010
type BookCreatedDTO struct {
1111
Title string `json:"title" form:"title" binding:"required"`
1212
Description string `json:"description" form:"description" binding:"required"`
13-
UserID string `json:"user_id,omitempty" form:"user_id,omitempty"`
13+
UserID uint64 `json:"user_id,omitempty" form:"user_id,omitempty"`
1414
}

Diff for: repository/book-repository.go

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package repository
2+
3+
import (
4+
"gogin/entity"
5+
6+
"gorm.io/gorm"
7+
)
8+
9+
type BookRepository interface {
10+
InsertBook(book entity.Book) entity.Book
11+
UpdateBook(book entity.Book) entity.Book
12+
DeleteBook(book entity.Book)
13+
AllBook() []entity.Book
14+
FindBookByID(bookID uint64) entity.Book
15+
}
16+
17+
type bookConnection struct {
18+
connection *gorm.DB
19+
}
20+
21+
func NewBookRepository(db *gorm.DB) BookRepository {
22+
return &bookConnection{
23+
connection: db,
24+
}
25+
}
26+
27+
func (db *bookConnection) InsertBook(book entity.Book) entity.Book {
28+
db.connection.Save(&book)
29+
db.connection.Preload("User").Find(&book)
30+
return book
31+
}
32+
33+
func (db *bookConnection) UpdateBook(book entity.Book) entity.Book {
34+
db.connection.Save(&book)
35+
db.connection.Preload("User").Find(&book)
36+
return book
37+
}
38+
39+
func (db *bookConnection) DeleteBook(book entity.Book) {
40+
db.connection.Delete(&book)
41+
}
42+
43+
func (db *bookConnection) AllBook() []entity.Book {
44+
var books []entity.Book
45+
db.connection.Preload("User").Find(&books)
46+
return books
47+
}
48+
49+
func (db *bookConnection) FindBookByID(bookID uint64) entity.Book {
50+
var book entity.Book
51+
db.connection.Preload("User").Find(&book, bookID)
52+
return book
53+
}

Diff for: repository/user-repository.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ func (db *userConnection) FindByEmail(email string) entity.User {
6767

6868
func (db *userConnection) ProfileUser(userID string) entity.User {
6969
var user entity.User
70-
db.connection.Find(&user, userID)
70+
db.connection.Preload("Books").Preload("Books.User").Find(&user, userID)
7171
return user
7272
}
7373

Diff for: server.go

+22-6
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package main
33
import (
44
"gogin/config"
55
"gogin/controller"
6+
"gogin/middleware"
67
"gogin/repository"
78
"gogin/service"
89

@@ -11,13 +12,19 @@ import (
1112
)
1213

1314
var (
14-
db *gorm.DB = config.SetupDBConnection()
15-
userRep repository.UserRepository = repository.NewUserRepository(db)
16-
authSevice service.AuthService = service.NewAuthService(userRep)
17-
jwtService service.JWTService = service.NewJWTService()
18-
userService service.UserService = service.NewUserService(userRep)
15+
db *gorm.DB = config.SetupDBConnection()
16+
17+
userRep repository.UserRepository = repository.NewUserRepository(db)
18+
bookRep repository.BookRepository = repository.NewBookRepository(db)
19+
authSevice service.AuthService = service.NewAuthService(userRep)
20+
21+
userService service.UserService = service.NewUserService(userRep)
22+
bookSer service.BookService = service.NewBookService(bookRep)
23+
jwtService service.JWTService = service.NewJWTService()
24+
1925
authController controller.AuthController = controller.NewAuthController(authSevice, jwtService)
2026
userController controller.UserController = controller.NewUserController(userService, jwtService)
27+
bookController controller.BookController = controller.NewBookController(bookSer, jwtService)
2128
)
2229

2330
func main() {
@@ -30,11 +37,20 @@ func main() {
3037
authRoutes.POST("/register", authController.Register)
3138
}
3239

33-
userRoute := r.Group("api/user")
40+
userRoute := r.Group("api/user", middleware.AuthorizeJWT(jwtService))
3441
{
3542
userRoute.POST("/update", userController.Update)
3643
userRoute.GET("/profile", userController.Profile)
3744
}
3845

46+
bookRoute := r.Group("api/books", middleware.AuthorizeJWT(jwtService))
47+
{
48+
bookRoute.GET("/", bookController.All)
49+
bookRoute.POST("/", bookController.Insert)
50+
bookRoute.PUT("/:id", bookController.Update)
51+
bookRoute.DELETE("/:id", bookController.Delete)
52+
bookRoute.GET("/:id", bookController.FindByID)
53+
}
54+
3955
r.Run()
4056
}

Diff for: service/book-service.go

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package service
2+
3+
import (
4+
"fmt"
5+
"gogin/dto"
6+
"gogin/entity"
7+
"gogin/repository"
8+
"log"
9+
10+
"github.com/mashingan/smapping"
11+
)
12+
13+
type BookService interface {
14+
Insert(book dto.BookCreatedDTO) entity.Book
15+
Update(book dto.BookUpdateDTO) entity.Book
16+
Delete(book entity.Book)
17+
All() []entity.Book
18+
FindByID(bookID uint64) entity.Book
19+
IsAllowedToEdit(userID string, bookID uint64) bool
20+
}
21+
22+
type bookService struct {
23+
bookRepository repository.BookRepository
24+
}
25+
26+
func NewBookService(bookRep repository.BookRepository) BookService {
27+
return &bookService{
28+
bookRepository: bookRep,
29+
}
30+
}
31+
32+
func (service *bookService) Insert(book dto.BookCreatedDTO) entity.Book {
33+
bookToInsert := entity.Book{}
34+
err := smapping.FillStruct(&bookToInsert, smapping.MapFields(&book))
35+
if err != nil {
36+
log.Fatalf("Failed map %v : ", err)
37+
}
38+
return service.bookRepository.InsertBook(bookToInsert)
39+
}
40+
41+
func (service *bookService) Update(book dto.BookUpdateDTO) entity.Book {
42+
bookToUpdate := entity.Book{}
43+
err := smapping.FillStruct(&bookToUpdate, smapping.MapFields(&book))
44+
if err != nil {
45+
log.Fatalf("Failed map %v : ", err)
46+
}
47+
return service.bookRepository.UpdateBook(bookToUpdate)
48+
49+
}
50+
51+
func (service *bookService) Delete(book entity.Book) {
52+
service.bookRepository.DeleteBook(book)
53+
}
54+
55+
func (service *bookService) All() []entity.Book {
56+
return service.bookRepository.AllBook()
57+
}
58+
59+
func (service *bookService) FindByID(bookID uint64) entity.Book {
60+
return service.bookRepository.FindBookByID(bookID)
61+
}
62+
63+
func (service *bookService) IsAllowedToEdit(userID string, bookID uint64) bool {
64+
book := service.bookRepository.FindBookByID(bookID)
65+
id := fmt.Sprintf("%v", book.UserID)
66+
return userID == id
67+
}

0 commit comments

Comments
 (0)