mirror of
https://github.com/Floriansylvain/RenewCMS.git
synced 2026-08-19 19:53:21 +02:00
Splat handler in their own files, added pagination
This commit is contained in:
@@ -6,6 +6,8 @@ The features are not complete, not tested and subject to many changes.
|
||||
|
||||
## Setup
|
||||
|
||||
Don't forget to setup the [Environment variables](#environment-variables)!
|
||||
|
||||
### Use with Docker
|
||||
|
||||
To **run** the app, run the command
|
||||
@@ -18,7 +20,7 @@ docker-compose up
|
||||
|
||||
TODO
|
||||
|
||||
## Environment variables
|
||||
### Environment variables
|
||||
|
||||
- ./env
|
||||
- APP_API_ADDRESS: `http://example.com`
|
||||
@@ -29,6 +31,10 @@ TODO
|
||||
- APP_FRONT_PORT: `1234`
|
||||
- APP_JWT_SECRET: `secret`
|
||||
|
||||
## API Usage
|
||||
|
||||
TODO
|
||||
|
||||
## Demo
|
||||
|
||||
TODO
|
||||
|
||||
+5
-5
@@ -63,11 +63,11 @@ func initArticlesRoutes(r *gin.RouterGroup) {
|
||||
articlesRouter := r.Group("/articles")
|
||||
articlesRouter.Use(corsMiddleware, api.AuthMiddleware.MiddlewareFunc())
|
||||
|
||||
articlesRouter.GET("/", articles.GetArticleHandler)
|
||||
articlesRouter.GET("/:id", articles.GetArticleHandler)
|
||||
articlesRouter.POST("/:id", articles.AddArticleHandler)
|
||||
articlesRouter.PUT("/:id", articles.EditArticleHandler)
|
||||
articlesRouter.DELETE("/:id", articles.DeleteArticleHandler)
|
||||
articlesRouter.GET("/", articles.Get)
|
||||
articlesRouter.GET("/:id", articles.Get)
|
||||
articlesRouter.POST("/:id", articles.Add)
|
||||
articlesRouter.PUT("/:id", articles.Edit)
|
||||
articlesRouter.DELETE("/:id", articles.Delete)
|
||||
}
|
||||
|
||||
func initGin() {
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
package articles
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/Floriansylvain/GohCMS/internal/api"
|
||||
"github.com/Floriansylvain/GohCMS/internal/database"
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
)
|
||||
|
||||
func Add(c *gin.Context) {
|
||||
var article Article
|
||||
article.TitleID = c.Params.ByName("id")
|
||||
if c.BindJSON(&article) != nil {
|
||||
api.SendBadRequest(c, "Could not correctly parse the article.")
|
||||
return
|
||||
}
|
||||
|
||||
document, err := bson.Marshal(article)
|
||||
if err != nil {
|
||||
api.SendBadRequest(c, "Could not correctly marshal the article.")
|
||||
return
|
||||
}
|
||||
|
||||
documents, _ := database.GetDocuments(articlesLocation, map[string]any{})
|
||||
if IsArticleIdAlreadyUsed(article.TitleID, documents) {
|
||||
api.SendBadRequest(c, fmt.Sprintf("Article ID '%v' already used.", article.TitleID))
|
||||
return
|
||||
}
|
||||
|
||||
err = database.PushDocument(articlesLocation, document)
|
||||
if err != nil {
|
||||
api.SendBadRequest(c, fmt.Sprintf(`Could not insert document(s) into DB: %v`, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
api.SendOk(c, "Article successfully added!")
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package articles
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/Floriansylvain/GohCMS/internal/api"
|
||||
"github.com/Floriansylvain/GohCMS/internal/database"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func Delete(c *gin.Context) {
|
||||
id := c.Params.ByName("id")
|
||||
|
||||
deleteCount, err := database.DeleteDocument(articlesLocation, map[string]any{"titleID": id})
|
||||
if err != nil {
|
||||
api.SendBadRequest(c, fmt.Sprintf(`Could not delete document(s) from DB: %v`, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
if deleteCount != 0 {
|
||||
api.SendOk(c, fmt.Sprintf("%d article(s) was/were successfully deleted!", deleteCount))
|
||||
} else {
|
||||
api.SendOk(c, "No articles were deleted.")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package articles
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/Floriansylvain/GohCMS/internal/api"
|
||||
"github.com/Floriansylvain/GohCMS/internal/database"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func Edit(c *gin.Context) {
|
||||
id := c.Params.ByName("id")
|
||||
|
||||
var articleUpdate database.DocumentUpdate
|
||||
articleUpdate.Filter = map[string]any{"titleID": id}
|
||||
c.BindJSON(&articleUpdate.Update)
|
||||
|
||||
editCount, err := database.EditDocument(articlesLocation, articleUpdate)
|
||||
if err != nil {
|
||||
api.SendBadRequest(c, fmt.Sprintf(`Could not edit document(s) from DB: %v`, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
if editCount != 0 {
|
||||
api.SendOk(c, fmt.Sprintf("%d article(s) was/were successfully edited!", editCount))
|
||||
} else {
|
||||
api.SendOk(c, "No articles were edited.")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package articles
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
|
||||
"github.com/Floriansylvain/GohCMS/internal/api"
|
||||
"github.com/Floriansylvain/GohCMS/internal/database"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func getApiFullUrl() string {
|
||||
return fmt.Sprintf("%v%v", os.Getenv("APP_API_ADDRESS"), os.Getenv("APP_BASE_API_PATH"))
|
||||
}
|
||||
|
||||
func getArticleSkipTakeFullUrl(skip uint64, take uint64) string {
|
||||
return fmt.Sprintf("%v/articles?skip=%v&take=%v", getApiFullUrl(), skip+take, take)
|
||||
}
|
||||
|
||||
func getBuiltGetResponse(articles []Article, skip uint64, take uint64) map[string]any {
|
||||
slicedArticles := articles[skip : skip+take]
|
||||
return map[string]any{
|
||||
"content": slicedArticles,
|
||||
"total": len(slicedArticles),
|
||||
"pagination": map[string]any{
|
||||
"skip": skip,
|
||||
"take": take,
|
||||
"links": map[string]any{
|
||||
"next": getArticleSkipTakeFullUrl(skip+take, take),
|
||||
"previous": getArticleSkipTakeFullUrl(skip-take, take),
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func parseUintQueryParam(c *gin.Context, param string) (uint64, error) {
|
||||
value, err := strconv.ParseUint(c.Query(param), 10, 0)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, fmt.Sprintf("%s query parameter must be a positive number.", param))
|
||||
}
|
||||
return value, err
|
||||
}
|
||||
|
||||
func getArticleIdFilter(titleID string) map[string]any {
|
||||
filter := map[string]any{}
|
||||
if titleID != "" {
|
||||
filter["titleID"] = titleID
|
||||
}
|
||||
return filter
|
||||
}
|
||||
|
||||
func Get(c *gin.Context) {
|
||||
titleID := c.Params.ByName("id")
|
||||
|
||||
skip, skipErr := parseUintQueryParam(c, "skip")
|
||||
take, takeErr := parseUintQueryParam(c, "take")
|
||||
if skipErr != nil || takeErr != nil {
|
||||
return
|
||||
}
|
||||
|
||||
articles, err := database.GetDocuments(articlesLocation, getArticleIdFilter(titleID))
|
||||
if err != nil {
|
||||
api.SendBadRequest(c, fmt.Sprintf("The ID '%v' doesn't match any article.", titleID))
|
||||
return
|
||||
}
|
||||
|
||||
articlesArray := ParseArticlesFromBytesToArray(articles)
|
||||
articlesArrayLength := uint64(len(articlesArray))
|
||||
if skip >= articlesArrayLength || take == 0 {
|
||||
c.JSON(http.StatusOK, map[string]any{
|
||||
"content": []string{},
|
||||
"total": "0",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, getBuiltGetResponse(articlesArray, skip, take))
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
package articles
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/Floriansylvain/GohCMS/internal/api"
|
||||
"github.com/Floriansylvain/GohCMS/internal/database"
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
)
|
||||
|
||||
func GetArticleHandler(c *gin.Context) {
|
||||
articleID := c.Params.ByName("id")
|
||||
|
||||
filter := gin.H{}
|
||||
if articleID != "" {
|
||||
filter["titleID"] = articleID
|
||||
}
|
||||
|
||||
articles, err := database.GetDocuments(articlesLocation, filter)
|
||||
if err != nil {
|
||||
api.SendBadRequest(c, fmt.Sprintf("The ID '%v' doesn't match any article.", articleID))
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, ParseArticlesFromBytesToArray(articles))
|
||||
}
|
||||
|
||||
func AddArticleHandler(c *gin.Context) {
|
||||
var article Article
|
||||
article.TitleID = c.Params.ByName("id")
|
||||
if c.BindJSON(&article) != nil {
|
||||
api.SendBadRequest(c, "Could not correctly parse the article.")
|
||||
return
|
||||
}
|
||||
|
||||
document, err := bson.Marshal(article)
|
||||
if err != nil {
|
||||
api.SendBadRequest(c, "Could not correctly marshal the article.")
|
||||
return
|
||||
}
|
||||
|
||||
documents, _ := database.GetDocuments(articlesLocation, gin.H{})
|
||||
if IsArticleIdAlreadyUsed(article.TitleID, documents) {
|
||||
api.SendBadRequest(c, fmt.Sprintf("Article ID '%v' already used.", article.TitleID))
|
||||
return
|
||||
}
|
||||
|
||||
err = database.PushDocument(articlesLocation, document)
|
||||
if err != nil {
|
||||
api.SendBadRequest(c, fmt.Sprintf(`Could not insert document(s) into DB: %v`, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
api.SendOk(c, "Article successfully added!")
|
||||
}
|
||||
|
||||
func DeleteArticleHandler(c *gin.Context) {
|
||||
id := c.Params.ByName("id")
|
||||
|
||||
deleteCount, err := database.DeleteDocument(articlesLocation, gin.H{"titleID": id})
|
||||
if err != nil {
|
||||
api.SendBadRequest(c, fmt.Sprintf(`Could not delete document(s) from DB: %v`, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
if deleteCount != 0 {
|
||||
api.SendOk(c, fmt.Sprintf("%d article(s) was/were successfully deleted!", deleteCount))
|
||||
} else {
|
||||
api.SendOk(c, "No articles were deleted.")
|
||||
}
|
||||
}
|
||||
|
||||
func EditArticleHandler(c *gin.Context) {
|
||||
id := c.Params.ByName("id")
|
||||
|
||||
var articleUpdate database.DocumentUpdate
|
||||
articleUpdate.Filter = gin.H{"titleID": id}
|
||||
c.BindJSON(&articleUpdate.Update)
|
||||
|
||||
editCount, err := database.EditDocument(articlesLocation, articleUpdate)
|
||||
if err != nil {
|
||||
api.SendBadRequest(c, fmt.Sprintf(`Could not edit document(s) from DB: %v`, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
if editCount != 0 {
|
||||
api.SendOk(c, fmt.Sprintf("%d article(s) was/were successfully edited!", editCount))
|
||||
} else {
|
||||
api.SendOk(c, "No articles were edited.")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user