diff --git a/cmd/main.go b/cmd/main.go index f1cbeb2..ff4e652 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -1,16 +1,16 @@ package main -// @title 58team blog backend -// @version 1.0 -// @description 58team blog's backend -// @termsOfService http://swagger.io/terms/ -// @contact.name API Support -// @contact.url http://www.swagger.io/support -// @contact.email support@swagger.io -// @license.name Apache 2.0 -// @license.url http://www.apache.org/licenses/LICENSE-2.0.html -// @host localhost:8080 -// @BasePath /api/v1 +// @title 58team blog backend +// @version 1.0 +// @description 58team blog's backend +// @termsOfService http://swagger.io/terms/ +// @contact.name API Support +// @contact.url http://www.swagger.io/support +// @contact.email support@swagger.io +// @license.name Apache 2.0 +// @license.url http://www.apache.org/licenses/LICENSE-2.0.html +// @host localhost:8080 +// @BasePath /api/v1 // @securityDefinitions.basic BasicAuth import ( diff --git a/docs/docs.go b/docs/docs.go index 969fa70..bd37c88 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -5,7 +5,7 @@ package docs import "github.com/swaggo/swag/v2" const docTemplate = `{ - "schemes": {{ marshal .Schemes }},"swagger":"2.0","info":{"description":"{{escape .Description}}","title":"{{.Title}}","termsOfService":"http://swagger.io/terms/","contact":{"name":"API Support","url":"http://www.swagger.io/support","email":"support@swagger.io"},"license":{"name":"Apache 2.0","url":"http://www.apache.org/licenses/LICENSE-2.0.html"},"version":"{{.Version}}"},"host":"{{.Host}}","basePath":"{{.BasePath}}","paths":{"/images/{path}":{"get":{"description":"get image by path","produces":["image/png","image/jpeg"],"summary":"Get an image by path","parameters":[{"type":"string","description":"Path to image","name":"path","in":"query","required":true}],"responses":{"200":{"description":"OK"}}}},"/post":{"get":{"description":"Return first 5 posts","produces":["application/json"],"tags":["post"],"summary":"Get all posts","responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/responses.GetListPostResponseItem"}}}}},"post":{"description":"Create new post in blog","consumes":["application/json"],"produces":["application/json"],"tags":["post"],"summary":"Create new post","parameters":[{"description":"Post data","name":"request","in":"body","required":true,"schema":{"$ref":"#/definitions/requests.CreatePostRequest"}}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/responses.PostResponse"}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/responses.ErrorResponse"}}}}},"/post/{id}":{"get":{"description":"get post by id","produces":["application/json"],"tags":["post"],"summary":"Get post by id","parameters":[{"type":"string","description":"Id of post","name":"id","in":"query","required":true}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/responses.PostResponse"}}}}},"put":{"description":"update post content","produces":["application/json"],"tags":["post"],"summary":"Update post content","parameters":[{"type":"string","description":"Id of post","name":"id","in":"query","required":true}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/responses.PostResponse"}}}}},"/post/{offset}":{"get":{"description":"return 5 posts after first offset posts","produces":["application/json"],"tags":["post"],"summary":"Get posts after offset","parameters":[{"type":"integer","description":"Offset of posts","name":"offset","in":"query","required":true}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/responses.GetListPostResponseItem"}}}}}}},"definitions":{"requests.CreatePostRequest":{"type":"object","required":["content","description","title","userId"],"properties":{"content":{"type":"string","minLength":36},"description":{"type":"string","maxLength":255,"minLength":8},"title":{"type":"string","maxLength":255,"minLength":8},"userId":{"type":"string"}}},"responses.ErrorResponse":{"type":"object","properties":{"error_code":{"type":"integer"},"message":{"type":"string"}}},"responses.GetListPostResponseItem":{"type":"object","properties":{"description":{"type":"string"},"id":{"type":"string"},"title":{"type":"string"}}},"responses.PostResponse":{"type":"object","properties":{"content":{"type":"string"},"createdAt":{"type":"string"},"description":{"type":"string"},"id":{"type":"string"},"title":{"type":"string"},"updatedAt":{"type":"string"},"userId":{"type":"string"}}}},"securityDefinitions":{"BasicAuth":{"type":"basic"}}}` + "schemes": {{ marshal .Schemes }},"swagger":"2.0","info":{"description":"{{escape .Description}}","title":"{{.Title}}","termsOfService":"http://swagger.io/terms/","contact":{"name":"API Support","url":"http://www.swagger.io/support","email":"support@swagger.io"},"license":{"name":"Apache 2.0","url":"http://www.apache.org/licenses/LICENSE-2.0.html"},"version":"{{.Version}}"},"host":"{{.Host}}","basePath":"{{.BasePath}}","paths":{"/images/{path}":{"get":{"description":"Creates new user in system","produces":["application/json"],"summary":"Create new user","parameters":[{"type":"string","description":"Path to image","name":"path","in":"query","required":true}],"responses":{"200":{"description":"OK"}}}},"/post":{"get":{"description":"Return first 5 posts","produces":["application/json"],"tags":["post"],"summary":"Get all posts","responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/responses.GetListPostResponseItem"}}},"500":{"description":"Internal Server Error","schema":{"$ref":"#/definitions/responses.ErrorResponse"}}}},"post":{"description":"Create new post in blog","consumes":["application/json"],"produces":["application/json"],"tags":["post"],"summary":"Create new post","parameters":[{"description":"Post data","name":"request","in":"body","required":true,"schema":{"$ref":"#/definitions/requests.CreatePostRequest"}}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/responses.PostResponse"}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/responses.ErrorResponse"}},"500":{"description":"Internal Server Error","schema":{"$ref":"#/definitions/responses.ErrorResponse"}}}}},"/post/offset/{offset}":{"get":{"description":"return 5 posts after first offset posts","produces":["application/json"],"tags":["post"],"summary":"Get posts after offset","parameters":[{"type":"integer","description":"Offset of posts","name":"offset","in":"path","required":true}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/responses.GetListPostResponseItem"}}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/responses.ErrorResponse"}}}}},"/post/{id}":{"get":{"description":"get post by id","produces":["application/json"],"tags":["post"],"summary":"Get post by id","parameters":[{"type":"string","description":"Id of post","name":"id","in":"path","required":true}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/responses.PostResponse"}}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/responses.ErrorResponse"}}}},"put":{"description":"update post content","produces":["application/json"],"tags":["post"],"summary":"Update post content","parameters":[{"type":"string","description":"Id of post","name":"id","in":"path","required":true},{"description":"Post data","name":"request","in":"body","required":true,"schema":{"$ref":"#/definitions/requests.PutPostRequest"}}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/responses.PostResponse"}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/responses.ErrorResponse"}}}},"delete":{"description":"Delete post by id","produces":["application/json"],"tags":["post"],"summary":"Delete post","parameters":[{"type":"string","description":"Id of post","name":"id","in":"path","required":true}],"responses":{"200":{"description":"OK"},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/responses.ErrorResponse"}}}}}},"definitions":{"requests.CreatePostRequest":{"type":"object","required":["content","description","title","userId"],"properties":{"content":{"type":"string","minLength":36},"description":{"type":"string","maxLength":255,"minLength":8},"title":{"type":"string","maxLength":255,"minLength":8},"userId":{"type":"string"}}},"requests.PutPostRequest":{"type":"object","properties":{"content":{"type":"string"},"description":{"type":"string"},"title":{"type":"string"}}},"responses.ErrorResponse":{"type":"object","properties":{"error_code":{"type":"integer"},"message":{"type":"string"}}},"responses.GetListPostResponseItem":{"type":"object","properties":{"description":{"type":"string"},"id":{"type":"string"},"title":{"type":"string"}}},"responses.PostResponse":{"type":"object","properties":{"content":{"type":"string"},"createdAt":{"type":"string"},"description":{"type":"string"},"id":{"type":"string"},"title":{"type":"string"},"updatedAt":{"type":"string"},"userId":{"type":"string"}}}},"securityDefinitions":{"BasicAuth":{"type":"basic"}}}` // SwaggerInfo holds exported Swagger Info so clients can modify it var SwaggerInfo = &swag.Spec{ diff --git a/docs/swagger.json b/docs/swagger.json index a76a0f6..ae46508 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -1 +1 @@ -{"swagger":"2.0","info":{"description":"58team blog's backend","title":"58team blog backend","termsOfService":"http://swagger.io/terms/","contact":{"name":"API Support","url":"http://www.swagger.io/support","email":"support@swagger.io"},"license":{"name":"Apache 2.0","url":"http://www.apache.org/licenses/LICENSE-2.0.html"},"version":"1.0"},"host":"localhost:8080","basePath":"/api/v1","paths":{"/images/{path}":{"get":{"description":"get image by path","produces":["image/png","image/jpeg"],"summary":"Get an image by path","parameters":[{"type":"string","description":"Path to image","name":"path","in":"query","required":true}],"responses":{"200":{"description":"OK"}}}},"/post":{"get":{"description":"Return first 5 posts","produces":["application/json"],"tags":["post"],"summary":"Get all posts","responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/responses.GetListPostResponseItem"}}}}},"post":{"description":"Create new post in blog","consumes":["application/json"],"produces":["application/json"],"tags":["post"],"summary":"Create new post","parameters":[{"description":"Post data","name":"request","in":"body","required":true,"schema":{"$ref":"#/definitions/requests.CreatePostRequest"}}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/responses.PostResponse"}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/responses.ErrorResponse"}}}}},"/post/{id}":{"get":{"description":"get post by id","produces":["application/json"],"tags":["post"],"summary":"Get post by id","parameters":[{"type":"string","description":"Id of post","name":"id","in":"query","required":true}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/responses.PostResponse"}}}}},"put":{"description":"update post content","produces":["application/json"],"tags":["post"],"summary":"Update post content","parameters":[{"type":"string","description":"Id of post","name":"id","in":"query","required":true}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/responses.PostResponse"}}}}},"/post/{offset}":{"get":{"description":"return 5 posts after first offset posts","produces":["application/json"],"tags":["post"],"summary":"Get posts after offset","parameters":[{"type":"integer","description":"Offset of posts","name":"offset","in":"query","required":true}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/responses.GetListPostResponseItem"}}}}}}},"definitions":{"requests.CreatePostRequest":{"type":"object","required":["content","description","title","userId"],"properties":{"content":{"type":"string","minLength":36},"description":{"type":"string","maxLength":255,"minLength":8},"title":{"type":"string","maxLength":255,"minLength":8},"userId":{"type":"string"}}},"responses.ErrorResponse":{"type":"object","properties":{"error_code":{"type":"integer"},"message":{"type":"string"}}},"responses.GetListPostResponseItem":{"type":"object","properties":{"description":{"type":"string"},"id":{"type":"string"},"title":{"type":"string"}}},"responses.PostResponse":{"type":"object","properties":{"content":{"type":"string"},"createdAt":{"type":"string"},"description":{"type":"string"},"id":{"type":"string"},"title":{"type":"string"},"updatedAt":{"type":"string"},"userId":{"type":"string"}}}},"securityDefinitions":{"BasicAuth":{"type":"basic"}}} \ No newline at end of file +{"swagger":"2.0","info":{"description":"58team blog's backend","title":"58team blog backend","termsOfService":"http://swagger.io/terms/","contact":{"name":"API Support","url":"http://www.swagger.io/support","email":"support@swagger.io"},"license":{"name":"Apache 2.0","url":"http://www.apache.org/licenses/LICENSE-2.0.html"},"version":"1.0"},"host":"localhost:8080","basePath":"/api/v1","paths":{"/images/{path}":{"get":{"description":"Creates new user in system","produces":["application/json"],"summary":"Create new user","parameters":[{"type":"string","description":"Path to image","name":"path","in":"query","required":true}],"responses":{"200":{"description":"OK"}}}},"/post":{"get":{"description":"Return first 5 posts","produces":["application/json"],"tags":["post"],"summary":"Get all posts","responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/responses.GetListPostResponseItem"}}},"500":{"description":"Internal Server Error","schema":{"$ref":"#/definitions/responses.ErrorResponse"}}}},"post":{"description":"Create new post in blog","consumes":["application/json"],"produces":["application/json"],"tags":["post"],"summary":"Create new post","parameters":[{"description":"Post data","name":"request","in":"body","required":true,"schema":{"$ref":"#/definitions/requests.CreatePostRequest"}}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/responses.PostResponse"}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/responses.ErrorResponse"}},"500":{"description":"Internal Server Error","schema":{"$ref":"#/definitions/responses.ErrorResponse"}}}}},"/post/offset/{offset}":{"get":{"description":"return 5 posts after first offset posts","produces":["application/json"],"tags":["post"],"summary":"Get posts after offset","parameters":[{"type":"integer","description":"Offset of posts","name":"offset","in":"path","required":true}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/responses.GetListPostResponseItem"}}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/responses.ErrorResponse"}}}}},"/post/{id}":{"get":{"description":"get post by id","produces":["application/json"],"tags":["post"],"summary":"Get post by id","parameters":[{"type":"string","description":"Id of post","name":"id","in":"path","required":true}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/responses.PostResponse"}}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/responses.ErrorResponse"}}}},"put":{"description":"update post content","produces":["application/json"],"tags":["post"],"summary":"Update post content","parameters":[{"type":"string","description":"Id of post","name":"id","in":"path","required":true},{"description":"Post data","name":"request","in":"body","required":true,"schema":{"$ref":"#/definitions/requests.PutPostRequest"}}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/responses.PostResponse"}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/responses.ErrorResponse"}}}},"delete":{"description":"Delete post by id","produces":["application/json"],"tags":["post"],"summary":"Delete post","parameters":[{"type":"string","description":"Id of post","name":"id","in":"path","required":true}],"responses":{"200":{"description":"OK"},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/responses.ErrorResponse"}}}}}},"definitions":{"requests.CreatePostRequest":{"type":"object","required":["content","description","title","userId"],"properties":{"content":{"type":"string","minLength":36},"description":{"type":"string","maxLength":255,"minLength":8},"title":{"type":"string","maxLength":255,"minLength":8},"userId":{"type":"string"}}},"requests.PutPostRequest":{"type":"object","properties":{"content":{"type":"string"},"description":{"type":"string"},"title":{"type":"string"}}},"responses.ErrorResponse":{"type":"object","properties":{"error_code":{"type":"integer"},"message":{"type":"string"}}},"responses.GetListPostResponseItem":{"type":"object","properties":{"description":{"type":"string"},"id":{"type":"string"},"title":{"type":"string"}}},"responses.PostResponse":{"type":"object","properties":{"content":{"type":"string"},"createdAt":{"type":"string"},"description":{"type":"string"},"id":{"type":"string"},"title":{"type":"string"},"updatedAt":{"type":"string"},"userId":{"type":"string"}}}},"securityDefinitions":{"BasicAuth":{"type":"basic"}}} \ No newline at end of file diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 5e7f99e..4449e5a 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -21,6 +21,15 @@ definitions: - title - userId type: object + requests.PutPostRequest: + properties: + content: + type: string + description: + type: string + title: + type: string + type: object responses.ErrorResponse: properties: error_code: @@ -70,7 +79,7 @@ info: paths: /images/{path}: get: - description: get image by path + description: Creates new user in system parameters: - description: Path to image in: query @@ -78,12 +87,11 @@ paths: required: true type: string produces: - - image/png - - image/jpeg + - application/json responses: "200": description: OK - summary: Get an image by path + summary: Create new user /post: get: description: Return first 5 posts @@ -96,6 +104,10 @@ paths: items: $ref: '#/definitions/responses.GetListPostResponseItem' type: array + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/responses.ErrorResponse' summary: Get all posts tags: - post @@ -121,15 +133,39 @@ paths: description: Bad Request schema: $ref: '#/definitions/responses.ErrorResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/responses.ErrorResponse' summary: Create new post tags: - post /post/{id}: + delete: + description: Delete post by id + parameters: + - description: Id of post + in: path + name: id + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + "400": + description: Bad Request + schema: + $ref: '#/definitions/responses.ErrorResponse' + summary: Delete post + tags: + - post get: description: get post by id parameters: - description: Id of post - in: query + in: path name: id required: true type: string @@ -142,6 +178,10 @@ paths: items: $ref: '#/definitions/responses.PostResponse' type: array + "400": + description: Bad Request + schema: + $ref: '#/definitions/responses.ErrorResponse' summary: Get post by id tags: - post @@ -149,10 +189,16 @@ paths: description: update post content parameters: - description: Id of post - in: query + in: path name: id required: true type: string + - description: Post data + in: body + name: request + required: true + schema: + $ref: '#/definitions/requests.PutPostRequest' produces: - application/json responses: @@ -160,15 +206,19 @@ paths: description: OK schema: $ref: '#/definitions/responses.PostResponse' + "400": + description: Bad Request + schema: + $ref: '#/definitions/responses.ErrorResponse' summary: Update post content tags: - post - /post/{offset}: + /post/offset/{offset}: get: description: return 5 posts after first offset posts parameters: - description: Offset of posts - in: query + in: path name: offset required: true type: integer @@ -181,6 +231,10 @@ paths: items: $ref: '#/definitions/responses.GetListPostResponseItem' type: array + "400": + description: Bad Request + schema: + $ref: '#/definitions/responses.ErrorResponse' summary: Get posts after offset tags: - post diff --git a/internal/application/interfaces/post_service.go b/internal/application/interfaces/post_service.go index 02b49f6..7bfe41b 100644 --- a/internal/application/interfaces/post_service.go +++ b/internal/application/interfaces/post_service.go @@ -11,6 +11,7 @@ type PostService interface { FindById(queries.PostFindByIdQuery) (*queries.PostFindByIdResult, error) FindAllByUserName(queries.PostFindAllByUserNameQuery) (*queries.PostFindAllByUserNameResult, error) GetAll() (*queries.PostGetAllResult, error) + GetAllOffset(int) (*queries.PostGetAllResult, error) Update(commands.UpdatePostCommand) (*common.PostResult, error) Delete(commands.DeletePostCommand) error } diff --git a/internal/application/services/post_service.go b/internal/application/services/post_service.go index ed45e85..f1633a5 100644 --- a/internal/application/services/post_service.go +++ b/internal/application/services/post_service.go @@ -7,6 +7,7 @@ import ( "58team_blog/internal/application/queries" "58team_blog/internal/domain/entities" "58team_blog/internal/domain/repository" + "errors" "fmt" "time" ) @@ -86,6 +87,22 @@ func (s *PostService) GetAll() (*queries.PostGetAllResult, error) { return result, nil } +func (s *PostService) GetAllOffset(offset int) (*queries.PostGetAllResult, error) { + if offset < 0 { + return nil, errors.New("offset is less than 0") + } + + posts, err := s.repo.GetAllOffset(offset) + + if err != nil { + return nil, err + } + + result := mapper.CreatePostGetAllResult(posts) + + return result, nil +} + func (s *PostService) Update(cmd commands.UpdatePostCommand) (*common.PostResult, error) { post, err := s.repo.FindById(cmd.Id) if err != nil { diff --git a/internal/domain/repository/post_repo.go b/internal/domain/repository/post_repo.go index 644da80..db5a147 100644 --- a/internal/domain/repository/post_repo.go +++ b/internal/domain/repository/post_repo.go @@ -11,6 +11,7 @@ type PostRepository interface { FindById(uuid.UUID) (*entities.Post, error) FindAllByUserName(string) ([]*entities.Post, error) GetAll() ([]*entities.Post, error) + GetAllOffset(int) ([]*entities.Post, error) Update(*entities.Post) error Delete(uuid.UUID) error } diff --git a/internal/infrastructure/db/repo/post_repo.go b/internal/infrastructure/db/repo/post_repo.go index c66e918..a58f1dc 100644 --- a/internal/infrastructure/db/repo/post_repo.go +++ b/internal/infrastructure/db/repo/post_repo.go @@ -3,6 +3,7 @@ package repo import ( "58team_blog/internal/domain/entities" "58team_blog/internal/infrastructure/db" + "strconv" "github.com/google/uuid" "github.com/jmoiron/sqlx" @@ -65,6 +66,15 @@ func (r *PostRepository) GetAll() ([]*entities.Post, error) { return entity_list, err } +func (r *PostRepository) GetAllOffset(offset int) ([]*entities.Post, error) { + var entity_list []*entities.Post + query := "SELECT * FROM " + entities.PostTable + " ORDER BY createdat, updatedat OFFSET " + strconv.Itoa(offset) + " LIMIT 5" + + err := r.conn.Conn.Select(&entity_list, query) + + return entity_list, err +} + func (r *PostRepository) Update(entity *entities.Post) error { query := "UPDATE " + entities.PostTable + "SET title=:title, description=:description, content=:content, updatedat=:updatedat WHERE id=:id" diff --git a/internal/interfaces/api/controllers/post_controller.go b/internal/interfaces/api/controllers/post_controller.go index 5b1c3f1..685fc45 100644 --- a/internal/interfaces/api/controllers/post_controller.go +++ b/internal/interfaces/api/controllers/post_controller.go @@ -9,6 +9,7 @@ import ( "58team_blog/internal/interfaces/api/responses" "log" "net/http" + "strconv" "github.com/gin-gonic/gin" "github.com/google/uuid" @@ -31,10 +32,10 @@ func CreatePostController(service *services.PostService) PostController { // @Tags post // @Accept json // @Produce json -// @Param request body requests.CreatePostRequest true "Post data" -// @Success 200 {object} responses.PostResponse -// @Failure 400 {object} responses.ErrorResponse -// @Failure 500 {object} responses.ErrorResponse +// @Param request body requests.CreatePostRequest true "Post data" +// @Success 200 {object} responses.PostResponse +// @Failure 400 {object} responses.ErrorResponse +// @Failure 500 {object} responses.ErrorResponse // @Router /post [post] func (r *PostController) Post(c *gin.Context) { var request requests.CreatePostRequest @@ -42,7 +43,7 @@ func (r *PostController) Post(c *gin.Context) { if err := c.BindJSON(&request); err != nil { log.Println(err) resp := responses.CreateErrorResponse(http.StatusBadRequest, "BadRequest") - c.IndentedJSON(resp.ErrorCode, resp) + c.JSON(resp.ErrorCode, resp) return } @@ -50,7 +51,7 @@ func (r *PostController) Post(c *gin.Context) { if err != nil { log.Println(err) resp := responses.CreateErrorResponse(http.StatusBadRequest, "Incorrect user id") - c.IndentedJSON(resp.ErrorCode, resp) + c.JSON(resp.ErrorCode, resp) return } @@ -65,13 +66,13 @@ func (r *PostController) Post(c *gin.Context) { if err != nil { log.Println(err) resp := responses.CreateErrorResponse(http.StatusInternalServerError, "Internal server error") - c.IndentedJSON(resp.ErrorCode, resp) + c.JSON(resp.ErrorCode, resp) return } response := dto.ResponseFromPostResult(res) - c.IndentedJSON(http.StatusOK, response) + c.JSON(http.StatusOK, response) } // GetAllPost godoc @@ -80,15 +81,15 @@ func (r *PostController) Post(c *gin.Context) { // @Description Return first 5 posts // @Tags post // @Produce json -// @Success 200 {array} responses.GetListPostResponseItem -// @Failure 500 {object} responses.ErrorResponse +// @Success 200 {array} responses.GetListPostResponseItem +// @Failure 500 {object} responses.ErrorResponse // @Router /post [get] func (r *PostController) GetAll(c *gin.Context) { result, err := r.service.GetAll() if err != nil { log.Println(err) resp := responses.CreateErrorResponse(http.StatusInternalServerError, "Internal server error") - c.IndentedJSON(resp.ErrorCode, resp) + c.JSON(resp.ErrorCode, resp) return } @@ -98,26 +99,48 @@ func (r *PostController) GetAll(c *gin.Context) { } // GetAllWithOffsetPost godoc -// @Summary Get posts after offset -// @Description return 5 posts after first offset posts -// @Tags post -// @Param offset query int true "Offset of posts" -// @Produce json -// @Success 200 {array} responses.GetListPostResponseItem -// @Router /post/{offset} [get] +// +// @Summary Get posts after offset +// @Description return 5 posts after first offset posts +// @Tags post +// @Param offset path int true "Offset of posts" +// @Produce json +// @Success 200 {array} responses.GetListPostResponseItem +// @Failure 400 {object} responses.ErrorResponse +// @Router /post/offset/{offset} [get] func (r *PostController) GetAllWithOffset(c *gin.Context) { + offset_param := c.Param("offset") + offset, err := strconv.Atoi(offset_param) + if err != nil { + log.Println("Post get all with offset error: ", err) + resp := responses.CreateErrorResponse(http.StatusBadRequest, "Bad request") + c.JSON(resp.ErrorCode, resp) + return + } + result, err := r.service.GetAllOffset(offset) + if err != nil { + log.Println("Post get all with offset error: ", err) + resp := responses.CreateErrorResponse(http.StatusBadRequest, "Bad request") + c.JSON(resp.ErrorCode, resp) + return + } + + res := dto.ResponseFromPostGetAllResult(result) + + c.JSON(http.StatusOK, res) } // GetByIdPost godoc -// @Summary Get post by id -// @Description get post by id -// @Tags post -// @Param id query string true "Id of post" -// @Produce json -// @Success 200 {array} responses.PostResponse -// @Failure 400 {object} responses.ErrorResponse -// @Router /post/{id} [get] +// +// @Summary Get post by id +// @Description get post by id +// @Tags post +// @Param id path string true "Id of post" +// @Produce json +// @Success 200 {array} responses.PostResponse +// @Failure 400 {object} responses.ErrorResponse +// @Router /post/{id} [get] func (r *PostController) GetById(c *gin.Context) { id := c.Param("id") @@ -147,36 +170,86 @@ func (r *PostController) GetById(c *gin.Context) { } // PutPost godoc -// @Summary Update post content -// @Description update post content -// @Tags post -// @Param id query string true "Id of post" // -// @Param request body requests.PutPostRequest true "Post data" +// @Summary Update post content +// @Description update post content +// @Tags post +// @Param id path string true "Id of post" // -// @Produce json -// @Success 200 {object} responses.PostResponse -// @Failure 400 {object} responses.ErrorResponse -// @Router /post/{id} [put] +// @Param request body requests.PutPostRequest true "Post data" +// +// @Produce json +// @Success 200 {object} responses.PostResponse +// @Failure 400 {object} responses.ErrorResponse +// @Router /post/{id} [put] func (r *PostController) Put(c *gin.Context) { var request requests.PutPostRequest + id := c.Param("id") + id_valid, err := uuid.Parse(id) + if err != nil { + log.Println("Post: invalid post id: ", err) + resp := responses.CreateErrorResponse(http.StatusBadRequest, "Bad request") + c.JSON(resp.ErrorCode, resp) + return + } + if err := c.BindJSON(request); err != nil { log.Println("Post request error: ", err) resp := responses.CreateErrorResponse(http.StatusBadRequest, "Bad request") c.JSON(resp.ErrorCode, resp) + return } + + cmd := commands.UpdatePostCommand{ + Id: id_valid, + Title: request.Title, + Description: request.Description, + Content: request.Content, + } + + post, err := r.service.Update(cmd) + if err != nil { + log.Println("Post service error: ", err) + resp := responses.CreateErrorResponse(http.StatusBadRequest, "Bad request") + c.JSON(resp.ErrorCode, resp) + return + } + + response := dto.ResponseFromPostResult(post) + c.JSON(http.StatusOK, response) } // Delete godoc -// @Summary Delete post -// @Description Delete post by id -// @Tags post -// @Param id query string true "Id of post" -// @Produce json -// @Success 200 -// @Router /post/{id} [delete] - +// +// @Summary Delete post +// @Description Delete post by id +// @Tags post +// @Param id path string true "Id of post" +// @Produce json +// @Success 200 +// @Failure 400 {object} responses.ErrorResponse +// @Router /post/{id} [delete] func (r *PostController) Delete(c *gin.Context) { + id := c.Param("id") + id_valid, err := uuid.Parse(id) + if err != nil { + log.Println("Post: invalid post id: ", err) + resp := responses.CreateErrorResponse(http.StatusBadRequest, "Bad request") + c.JSON(resp.ErrorCode, resp) + return + } + cmd := commands.DeletePostCommand{ + Id: id_valid, + } + err = r.service.Delete(cmd) + if err != nil { + log.Println("Post delete error: ", err) + resp := responses.CreateErrorResponse(http.StatusBadRequest, "Bad request") + c.JSON(resp.ErrorCode, resp) + return + } + + c.Status(http.StatusOK) } diff --git a/internal/interfaces/api/controllers/user_controller.go b/internal/interfaces/api/controllers/user_controller.go index 42a2af8..6591806 100644 --- a/internal/interfaces/api/controllers/user_controller.go +++ b/internal/interfaces/api/controllers/user_controller.go @@ -19,9 +19,9 @@ func CreateUserController(service *services.UserService) UserController { // @Summary Create new user // @Description Creates new user in system // @Param path query string true "Path to image" -// @Produce -// @Success 200 -// @Router /images/{path} [get] +// @Produce json +// @Success 200 +// @Router /images/{path} [get] func (r *UserController) Post(c *gin.Context) { // TODO: return image panic("Not implemented") diff --git a/internal/interfaces/route.go b/internal/interfaces/route.go index bc9b570..c42cf76 100644 --- a/internal/interfaces/route.go +++ b/internal/interfaces/route.go @@ -11,8 +11,10 @@ func BindPostAdmin(service *services.PostService, group *gin.RouterGroup) { post := controllers.CreatePostController(service) g := group.Group("/post") - g.GET("/", post.GetAllPost) - g.GET("/:id", post.GetByIdPost) - g.POST("/", post.PostPost) - g.PUT("/:id", post.PutPost) + g.GET("/", post.GetAll) + g.GET("/offset/:offset", post.GetAllWithOffset) + g.GET("/:id", post.GetById) + g.POST("/", post.Post) + g.PUT("/:id", post.Put) + g.DELETE("/:id", post.Delete) } diff --git a/migrate b/migrate deleted file mode 100755 index d6364f6..0000000 Binary files a/migrate and /dev/null differ