Files
assetx/webapp-back/articles/routers.go

252 lines
8.6 KiB
Go
Raw Normal View History

package articles
import (
"errors"
"github.com/gin-gonic/gin"
"github.com/gothinkster/golang-gin-realworld-example-app/common"
"github.com/gothinkster/golang-gin-realworld-example-app/users"
"gorm.io/gorm"
"net/http"
"strconv"
)
func ArticlesRegister(router *gin.RouterGroup) {
router.GET("/feed", ArticleFeed)
router.POST("", ArticleCreate)
router.POST("/", ArticleCreate)
router.PUT("/:slug", ArticleUpdate)
router.PUT("/:slug/", ArticleUpdate)
router.DELETE("/:slug", ArticleDelete)
router.POST("/:slug/favorite", ArticleFavorite)
router.DELETE("/:slug/favorite", ArticleUnfavorite)
router.POST("/:slug/comments", ArticleCommentCreate)
router.DELETE("/:slug/comments/:id", ArticleCommentDelete)
}
func ArticlesAnonymousRegister(router *gin.RouterGroup) {
router.GET("", ArticleList)
router.GET("/", ArticleList)
router.GET("/:slug", ArticleRetrieve)
router.GET("/:slug/comments", ArticleCommentList)
}
func TagsAnonymousRegister(router *gin.RouterGroup) {
router.GET("", TagList)
router.GET("/", TagList)
}
func ArticleCreate(c *gin.Context) {
articleModelValidator := NewArticleModelValidator()
if err := articleModelValidator.Bind(c); err != nil {
c.JSON(http.StatusUnprocessableEntity, common.NewValidatorError(err))
return
}
//fmt.Println(articleModelValidator.articleModel.Author.UserModel)
if err := SaveOne(&articleModelValidator.articleModel); err != nil {
c.JSON(http.StatusUnprocessableEntity, common.NewError("database", err))
return
}
serializer := ArticleSerializer{c, articleModelValidator.articleModel}
c.JSON(http.StatusCreated, gin.H{"article": serializer.Response()})
}
func ArticleList(c *gin.Context) {
//condition := ArticleModel{}
tag := c.Query("tag")
author := c.Query("author")
favorited := c.Query("favorited")
limit := c.Query("limit")
offset := c.Query("offset")
articleModels, modelCount, err := FindManyArticle(tag, author, limit, offset, favorited)
if err != nil {
c.JSON(http.StatusNotFound, common.NewError("articles", errors.New("Invalid param")))
return
}
serializer := ArticlesSerializer{c, articleModels}
c.JSON(http.StatusOK, gin.H{"articles": serializer.Response(), "articlesCount": modelCount})
}
func ArticleFeed(c *gin.Context) {
limit := c.Query("limit")
offset := c.Query("offset")
myUserModel := c.MustGet("my_user_model").(users.UserModel)
if myUserModel.ID == 0 {
c.AbortWithError(http.StatusUnauthorized, errors.New("{error : \"Require auth!\"}"))
return
}
articleUserModel := GetArticleUserModel(myUserModel)
articleModels, modelCount, err := articleUserModel.GetArticleFeed(limit, offset)
if err != nil {
c.JSON(http.StatusNotFound, common.NewError("articles", errors.New("Invalid param")))
return
}
serializer := ArticlesSerializer{c, articleModels}
c.JSON(http.StatusOK, gin.H{"articles": serializer.Response(), "articlesCount": modelCount})
}
func ArticleRetrieve(c *gin.Context) {
slug := c.Param("slug")
articleModel, err := FindOneArticle(&ArticleModel{Slug: slug})
if err != nil {
c.JSON(http.StatusNotFound, common.NewError("articles", errors.New("Invalid slug")))
return
}
serializer := ArticleSerializer{c, articleModel}
c.JSON(http.StatusOK, gin.H{"article": serializer.Response()})
}
func ArticleUpdate(c *gin.Context) {
slug := c.Param("slug")
articleModel, err := FindOneArticle(&ArticleModel{Slug: slug})
if err != nil {
c.JSON(http.StatusNotFound, common.NewError("articles", errors.New("Invalid slug")))
return
}
// Check if current user is the author
myUserModel := c.MustGet("my_user_model").(users.UserModel)
articleUserModel := GetArticleUserModel(myUserModel)
if articleModel.AuthorID != articleUserModel.ID {
c.JSON(http.StatusForbidden, common.NewError("article", errors.New("you are not the author")))
return
}
articleModelValidator := NewArticleModelValidatorFillWith(articleModel)
if err := articleModelValidator.Bind(c); err != nil {
c.JSON(http.StatusUnprocessableEntity, common.NewValidatorError(err))
return
}
articleModelValidator.articleModel.ID = articleModel.ID
if err := articleModel.Update(articleModelValidator.articleModel); err != nil {
c.JSON(http.StatusUnprocessableEntity, common.NewError("database", err))
return
}
serializer := ArticleSerializer{c, articleModel}
c.JSON(http.StatusOK, gin.H{"article": serializer.Response()})
}
func ArticleDelete(c *gin.Context) {
slug := c.Param("slug")
articleModel, err := FindOneArticle(&ArticleModel{Slug: slug})
if err == nil {
// Article exists, check authorization
myUserModel := c.MustGet("my_user_model").(users.UserModel)
articleUserModel := GetArticleUserModel(myUserModel)
if articleModel.AuthorID != articleUserModel.ID {
c.JSON(http.StatusForbidden, common.NewError("article", errors.New("you are not the author")))
return
}
}
// Delete regardless of existence (idempotent)
if err := DeleteArticleModel(&ArticleModel{Slug: slug}); err != nil {
c.JSON(http.StatusUnprocessableEntity, common.NewError("database", err))
return
}
c.JSON(http.StatusOK, gin.H{"article": "delete success"})
}
func ArticleFavorite(c *gin.Context) {
slug := c.Param("slug")
articleModel, err := FindOneArticle(&ArticleModel{Slug: slug})
if err != nil {
c.JSON(http.StatusNotFound, common.NewError("articles", errors.New("Invalid slug")))
return
}
myUserModel := c.MustGet("my_user_model").(users.UserModel)
if err = articleModel.favoriteBy(GetArticleUserModel(myUserModel)); err != nil {
c.JSON(http.StatusUnprocessableEntity, common.NewError("database", err))
return
}
serializer := ArticleSerializer{c, articleModel}
c.JSON(http.StatusOK, gin.H{"article": serializer.Response()})
}
func ArticleUnfavorite(c *gin.Context) {
slug := c.Param("slug")
articleModel, err := FindOneArticle(&ArticleModel{Slug: slug})
if err != nil {
c.JSON(http.StatusNotFound, common.NewError("articles", errors.New("Invalid slug")))
return
}
myUserModel := c.MustGet("my_user_model").(users.UserModel)
if err = articleModel.unFavoriteBy(GetArticleUserModel(myUserModel)); err != nil {
c.JSON(http.StatusUnprocessableEntity, common.NewError("database", err))
return
}
serializer := ArticleSerializer{c, articleModel}
c.JSON(http.StatusOK, gin.H{"article": serializer.Response()})
}
func ArticleCommentCreate(c *gin.Context) {
slug := c.Param("slug")
articleModel, err := FindOneArticle(&ArticleModel{Slug: slug})
if err != nil {
c.JSON(http.StatusNotFound, common.NewError("comment", errors.New("Invalid slug")))
return
}
commentModelValidator := NewCommentModelValidator()
if err := commentModelValidator.Bind(c); err != nil {
c.JSON(http.StatusUnprocessableEntity, common.NewValidatorError(err))
return
}
commentModelValidator.commentModel.Article = articleModel
if err := SaveOne(&commentModelValidator.commentModel); err != nil {
c.JSON(http.StatusUnprocessableEntity, common.NewError("database", err))
return
}
serializer := CommentSerializer{c, commentModelValidator.commentModel}
c.JSON(http.StatusCreated, gin.H{"comment": serializer.Response()})
}
func ArticleCommentDelete(c *gin.Context) {
id64, err := strconv.ParseUint(c.Param("id"), 10, 32)
if err != nil {
c.JSON(http.StatusNotFound, common.NewError("comment", errors.New("Invalid id")))
return
}
id := uint(id64)
commentModel, err := FindOneComment(&CommentModel{Model: gorm.Model{ID: id}})
if err == nil {
// Comment exists, check authorization
myUserModel := c.MustGet("my_user_model").(users.UserModel)
articleUserModel := GetArticleUserModel(myUserModel)
if commentModel.AuthorID != articleUserModel.ID {
c.JSON(http.StatusForbidden, common.NewError("comment", errors.New("you are not the author")))
return
}
}
// Delete regardless of existence (idempotent)
if err := DeleteCommentModel([]uint{id}); err != nil {
c.JSON(http.StatusUnprocessableEntity, common.NewError("database", err))
return
}
c.JSON(http.StatusOK, gin.H{"comment": "delete success"})
}
func ArticleCommentList(c *gin.Context) {
slug := c.Param("slug")
articleModel, err := FindOneArticle(&ArticleModel{Slug: slug})
if err != nil {
c.JSON(http.StatusNotFound, common.NewError("comments", errors.New("Invalid slug")))
return
}
err = articleModel.getComments()
if err != nil {
c.JSON(http.StatusNotFound, common.NewError("comments", errors.New("Database error")))
return
}
serializer := CommentsSerializer{c, articleModel.Comments}
c.JSON(http.StatusOK, gin.H{"comments": serializer.Response()})
}
func TagList(c *gin.Context) {
tagModels, err := getAllTags()
if err != nil {
c.JSON(http.StatusNotFound, common.NewError("articles", errors.New("Invalid param")))
return
}
serializer := TagsSerializer{c, tagModels}
c.JSON(http.StatusOK, gin.H{"tags": serializer.Response()})
}