From 9ec570688c2a7e9739c3c084bd95134e30b32218 Mon Sep 17 00:00:00 2001 From: d3m0k1d Date: Sat, 14 Feb 2026 15:35:25 +0300 Subject: [PATCH] feat: update docs models responses --- backend/Makefile | 1 + backend/docs/docs.go | 151 ++++++++++++++++++--- backend/docs/swagger.json | 151 ++++++++++++++++++--- backend/docs/swagger.yaml | 95 ++++++++++--- backend/internal/handlers/post_handlers.go | 64 +++++---- backend/internal/models/responses.go | 27 ++++ 6 files changed, 405 insertions(+), 84 deletions(-) create mode 100644 backend/internal/models/responses.go diff --git a/backend/Makefile b/backend/Makefile index 9e3eea8..10bad81 100644 --- a/backend/Makefile +++ b/backend/Makefile @@ -26,6 +26,7 @@ docs-upd: docker: + swag init -g ./cmd/main.go --parseDependency --parseInternal docker build -t backend . run-docker: diff --git a/backend/docs/docs.go b/backend/docs/docs.go index cee2fdf..8fb7a5b 100644 --- a/backend/docs/docs.go +++ b/backend/docs/docs.go @@ -99,6 +99,24 @@ const docTemplate = `{ "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_storage.PostReq" } } + }, + "400": { + "description": "Invalid ID format", + "schema": { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.ErrorResponse" + } + }, + "404": { + "description": "No Post found", + "schema": { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.ErrorResponse" + } + }, + "500": { + "description": "Internal server error", + "schema": { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.ErrorResponse" + } } } }, @@ -129,13 +147,25 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_storage.PostReq" + "allOf": [ + { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.SuccessResponse" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_storage.Post" + } + } + } + ] } }, "400": { - "description": "Bad Request", + "description": "Invalid request", "schema": { - "$ref": "#/definitions/gin.H" + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.ErrorResponse" } } } @@ -167,34 +197,37 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_storage.PostReq" + "allOf": [ + { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.SuccessResponse" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_storage.PostReq" + } + } + } + ] } }, "400": { "description": "Invalid ID format", "schema": { - "type": "object", - "additionalProperties": { - "type": "string" - } + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.ErrorResponse" } }, "404": { "description": "Post not found", "schema": { - "type": "object", - "additionalProperties": { - "type": "string" - } + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.ErrorResponse" } }, "500": { "description": "Internal server error", "schema": { - "type": "object", - "additionalProperties": { - "type": "string" - } + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.ErrorResponse" } } } @@ -233,7 +266,31 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_storage.PostCreate" + "allOf": [ + { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.SuccessResponse" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_storage.PostCreate" + } + } + } + ] + } + }, + "400": { + "description": "Invalid ID format", + "schema": { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.ErrorResponse" + } + }, + "500": { + "description": "Internal server error", + "schema": { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.ErrorResponse" } } } @@ -263,7 +320,37 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_storage.Post" + "allOf": [ + { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.SuccessResponse" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_storage.Post" + } + } + } + ] + } + }, + "400": { + "description": "Invalid ID format", + "schema": { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.ErrorResponse" + } + }, + "404": { + "description": "Post not found", + "schema": { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.ErrorResponse" + } + }, + "500": { + "description": "Internal server error", + "schema": { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.ErrorResponse" } } } @@ -271,9 +358,33 @@ const docTemplate = `{ } }, "definitions": { - "gin.H": { + "gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.ErrorDetail": { "type": "object", - "additionalProperties": {} + "properties": { + "code": { + "type": "integer" + }, + "detail": { + "type": "string" + }, + "message": { + "type": "string" + } + } + }, + "gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.ErrorResponse": { + "type": "object", + "properties": { + "error": { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.ErrorDetail" + } + } + }, + "gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.SuccessResponse": { + "type": "object", + "properties": { + "data": {} + } }, "gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_storage.Post": { "type": "object", diff --git a/backend/docs/swagger.json b/backend/docs/swagger.json index 3b0aed7..fe2e9e7 100644 --- a/backend/docs/swagger.json +++ b/backend/docs/swagger.json @@ -88,6 +88,24 @@ "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_storage.PostReq" } } + }, + "400": { + "description": "Invalid ID format", + "schema": { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.ErrorResponse" + } + }, + "404": { + "description": "No Post found", + "schema": { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.ErrorResponse" + } + }, + "500": { + "description": "Internal server error", + "schema": { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.ErrorResponse" + } } } }, @@ -118,13 +136,25 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_storage.PostReq" + "allOf": [ + { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.SuccessResponse" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_storage.Post" + } + } + } + ] } }, "400": { - "description": "Bad Request", + "description": "Invalid request", "schema": { - "$ref": "#/definitions/gin.H" + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.ErrorResponse" } } } @@ -156,34 +186,37 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_storage.PostReq" + "allOf": [ + { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.SuccessResponse" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_storage.PostReq" + } + } + } + ] } }, "400": { "description": "Invalid ID format", "schema": { - "type": "object", - "additionalProperties": { - "type": "string" - } + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.ErrorResponse" } }, "404": { "description": "Post not found", "schema": { - "type": "object", - "additionalProperties": { - "type": "string" - } + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.ErrorResponse" } }, "500": { "description": "Internal server error", "schema": { - "type": "object", - "additionalProperties": { - "type": "string" - } + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.ErrorResponse" } } } @@ -222,7 +255,31 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_storage.PostCreate" + "allOf": [ + { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.SuccessResponse" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_storage.PostCreate" + } + } + } + ] + } + }, + "400": { + "description": "Invalid ID format", + "schema": { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.ErrorResponse" + } + }, + "500": { + "description": "Internal server error", + "schema": { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.ErrorResponse" } } } @@ -252,7 +309,37 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_storage.Post" + "allOf": [ + { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.SuccessResponse" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_storage.Post" + } + } + } + ] + } + }, + "400": { + "description": "Invalid ID format", + "schema": { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.ErrorResponse" + } + }, + "404": { + "description": "Post not found", + "schema": { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.ErrorResponse" + } + }, + "500": { + "description": "Internal server error", + "schema": { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.ErrorResponse" } } } @@ -260,9 +347,33 @@ } }, "definitions": { - "gin.H": { + "gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.ErrorDetail": { "type": "object", - "additionalProperties": {} + "properties": { + "code": { + "type": "integer" + }, + "detail": { + "type": "string" + }, + "message": { + "type": "string" + } + } + }, + "gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.ErrorResponse": { + "type": "object", + "properties": { + "error": { + "$ref": "#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.ErrorDetail" + } + } + }, + "gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.SuccessResponse": { + "type": "object", + "properties": { + "data": {} + } }, "gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_storage.Post": { "type": "object", diff --git a/backend/docs/swagger.yaml b/backend/docs/swagger.yaml index b23bff6..e90652a 100644 --- a/backend/docs/swagger.yaml +++ b/backend/docs/swagger.yaml @@ -1,6 +1,21 @@ definitions: - gin.H: - additionalProperties: {} + gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.ErrorDetail: + properties: + code: + type: integer + detail: + type: string + message: + type: string + type: object + gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.ErrorResponse: + properties: + error: + $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.ErrorDetail' + type: object + gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.SuccessResponse: + properties: + data: {} type: object gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_storage.Post: properties: @@ -87,6 +102,18 @@ paths: items: $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_storage.PostReq' type: array + "400": + description: Invalid ID format + schema: + $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.ErrorResponse' + "404": + description: No Post found + schema: + $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.ErrorResponse' + "500": + description: Internal server error + schema: + $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.ErrorResponse' summary: Get all posts tags: - posts @@ -107,11 +134,16 @@ paths: "200": description: OK schema: - $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_storage.PostReq' + allOf: + - $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.SuccessResponse' + - properties: + data: + $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_storage.Post' + type: object "400": - description: Bad Request + description: Invalid request schema: - $ref: '#/definitions/gin.H' + $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.ErrorResponse' summary: Create post tags: - posts @@ -132,7 +164,24 @@ paths: "200": description: OK schema: - $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_storage.Post' + allOf: + - $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.SuccessResponse' + - properties: + data: + $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_storage.Post' + type: object + "400": + description: Invalid ID format + schema: + $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.ErrorResponse' + "404": + description: Post not found + schema: + $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.ErrorResponse' + "500": + description: Internal server error + schema: + $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.ErrorResponse' summary: Delete post tags: - posts @@ -152,25 +201,24 @@ paths: "200": description: OK schema: - $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_storage.PostReq' + allOf: + - $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.SuccessResponse' + - properties: + data: + $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_storage.PostReq' + type: object "400": description: Invalid ID format schema: - additionalProperties: - type: string - type: object + $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.ErrorResponse' "404": description: Post not found schema: - additionalProperties: - type: string - type: object + $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.ErrorResponse' "500": description: Internal server error schema: - additionalProperties: - type: string - type: object + $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.ErrorResponse' summary: Get post by id tags: - posts @@ -196,7 +244,20 @@ paths: "200": description: OK schema: - $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_storage.PostCreate' + allOf: + - $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.SuccessResponse' + - properties: + data: + $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_storage.PostCreate' + type: object + "400": + description: Invalid ID format + schema: + $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.ErrorResponse' + "500": + description: Internal server error + schema: + $ref: '#/definitions/gitea_d3m0k1d_ru_d3m0k1d_d3m0k1d_ru_backend_internal_models.ErrorResponse' summary: Update post tags: - posts diff --git a/backend/internal/handlers/post_handlers.go b/backend/internal/handlers/post_handlers.go index f024dc3..52017ab 100644 --- a/backend/internal/handlers/post_handlers.go +++ b/backend/internal/handlers/post_handlers.go @@ -4,6 +4,7 @@ import ( "strconv" "gitea.d3m0k1d.ru/d3m0k1d/d3m0k1d.ru/backend/internal/logger" + "gitea.d3m0k1d.ru/d3m0k1d/d3m0k1d.ru/backend/internal/models" "gitea.d3m0k1d.ru/d3m0k1d/d3m0k1d.ru/backend/internal/repositories" "gitea.d3m0k1d.ru/d3m0k1d/d3m0k1d.ru/backend/internal/storage" "github.com/gin-gonic/gin" @@ -25,19 +26,22 @@ func NewPostHandlers(repo repositories.PostRepository) *PostHandlers { // @Accept json // @Produce json // @Success 200 {object} []storage.PostReq +// @Failure 404 {object} models.ErrorResponse "No Post found" +// @Failure 500 {object} models.ErrorResponse "Internal server error" +// @Failure 400 {object} models.ErrorResponse "Invalid ID format" // @Router /posts [get] func (h *PostHandlers) GetPosts(c *gin.Context) { var result []storage.PostReq result, err := h.repo.GetAll(c.Request.Context()) if err != nil { h.logger.Error("error request: " + err.Error()) - c.Status(500) + models.Error(c, 500, "Internal server error", err.Error()) } if result == nil { - c.JSON(200, gin.H{"Status": "No Post found"}) + models.Error(c, 404, "No Post found", "") } h.logger.Info("200 OK GET /posts") - c.JSON(200, result) + models.Success(c, result) } // GetPost godoc @@ -47,35 +51,35 @@ func (h *PostHandlers) GetPosts(c *gin.Context) { // @Accept json // @Param id path int true "Post ID" // @Produce json -// @Success 200 {object} storage.PostReq -// @Failure 400 {object} map[string]string "Invalid ID format" -// @Failure 404 {object} map[string]string "Post not found" -// @Failure 500 {object} map[string]string "Internal server error" +// @Success 200 {object} models.SuccessResponse{data=storage.PostReq} +// @Failure 400 {object} models.ErrorResponse "Invalid ID format" +// @Failure 404 {object} models.ErrorResponse "Post not found" +// @Failure 500 {object} models.ErrorResponse "Internal server error" // @Router /posts/{id} [get] func (h *PostHandlers) GetPost(c *gin.Context) { var result storage.PostReq last_id, err := h.repo.GetLastID(c.Request.Context()) if err != nil { h.logger.Error("error request: " + err.Error()) - c.Status(500) + models.Error(c, 500, "Internal server error", err.Error()) } id_p := c.Param("id") id, err := strconv.Atoi(id_p) if err != nil { h.logger.Error("error request: " + err.Error()) - c.JSON(400, gin.H{"error": "Invalid ID format"}) + models.Error(c, 400, "Invalid ID format", err.Error()) } if id > last_id { - c.JSON(404, gin.H{"error": "Post not found"}) + models.Error(c, 404, "Post not found", "") return } result, err = h.repo.GetByID(c.Request.Context(), id) if err != nil { h.logger.Error("error request: " + err.Error()) - c.Status(500) + models.Error(c, 500, "Internal server error", err.Error()) } h.logger.Info("200 OK GET /posts/" + id_p) - c.JSON(200, result) + models.Success(c, result) } @@ -86,14 +90,14 @@ func (h *PostHandlers) GetPost(c *gin.Context) { // @Accept json // @Produce json // @Param post body storage.PostCreate true "Post data" -// @Success 200 {object} storage.PostReq -// @Failure 400 {object} gin.H +// @Success 200 {object} models.SuccessResponse{data=storage.Post} +// @Failure 400 {object} models.ErrorResponse "Invalid request" // @Router /posts [post] func (h *PostHandlers) CreatePost(c *gin.Context) { var req storage.PostCreate if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(400, gin.H{"error": err.Error()}) + models.Error(c, 400, "Invalid request", err.Error()) return } @@ -103,11 +107,11 @@ func (h *PostHandlers) CreatePost(c *gin.Context) { } if err := h.repo.Create(c.Request.Context(), post); err != nil { - c.JSON(500, gin.H{"error": err.Error()}) + models.Error(c, 500, "Internal server error", err.Error()) return } - c.JSON(200, post) + models.Success(c, post) } // UpdatePost godoc @@ -118,27 +122,30 @@ func (h *PostHandlers) CreatePost(c *gin.Context) { // @Param id path int true "Post ID" // @Param post body storage.PostCreate true "Post data" // @Produce json -// @Success 200 {object} storage.PostCreate +// @Success 200 {object} models.SuccessResponse{data=storage.PostCreate} +// @Failure 400 {object} models.ErrorResponse "Invalid ID format" +// @Failure 500 {object} models.ErrorResponse "Internal server error" +// Failure 404 {object} models.ErrorResponse "Post not found" // @Router /posts/{id} [put] func (h *PostHandlers) UpdatePost(c *gin.Context) { id_p := c.Param("id") id, err := strconv.Atoi(id_p) if err != nil { h.logger.Error("error request: " + err.Error()) - c.Status(500) + models.Error(c, 500, "Internal server error", err.Error()) } var req storage.Post if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(400, gin.H{"error": err.Error()}) + models.Error(c, 400, "Invalid request", err.Error()) return } err = h.repo.Update(c.Request.Context(), id, req) if err != nil { - c.JSON(500, gin.H{"error": err.Error()}) + models.Error(c, 500, "Internal server error", err.Error()) return } - c.JSON(200, req) + models.Success(c, req) h.logger.Info("200 OK PUT /posts/" + id_p) } @@ -149,26 +156,29 @@ func (h *PostHandlers) UpdatePost(c *gin.Context) { // @Param id path int true "Post ID" // @Accept json // @Produce json -// @Success 200 {object} storage.Post +// @Failure 404 {object} models.ErrorResponse "Post not found" +// @Failure 400 {object} models.ErrorResponse "Invalid ID format" +// @Failure 500 {object} models.ErrorResponse "Internal server error" +// @Success 200 {object} models.SuccessResponse{data=storage.Post} // @Router /posts/{id} [delete] func (h *PostHandlers) DeletePost(c *gin.Context) { id_p := c.Param("id") id, err := strconv.Atoi(id_p) if err != nil { h.logger.Error("error request: " + err.Error()) - c.JSON(400, gin.H{"error": "Invalid ID format"}) + models.Error(c, 400, "Invalid ID format", err.Error()) } exsist := h.repo.IsExist(c.Request.Context(), id) if !exsist { - c.JSON(404, gin.H{"error": "Post not found"}) + models.Error(c, 404, "Post not found", "") return } err = h.repo.Delete(c.Request.Context(), id) if err != nil { - c.JSON(500, gin.H{"error": err.Error()}) + models.Error(c, 500, "Internal server error", err.Error()) return } h.logger.Info("200 OK DELETE /posts/" + id_p) - c.JSON(200, gin.H{"Status": "Post deleted"}) + models.Success(c, "Post deleted") } diff --git a/backend/internal/models/responses.go b/backend/internal/models/responses.go new file mode 100644 index 0000000..121a88d --- /dev/null +++ b/backend/internal/models/responses.go @@ -0,0 +1,27 @@ +package models + +import ( + "github.com/gin-gonic/gin" +) + +type SuccessResponse struct { + Data interface{} `json:"data"` +} + +type ErrorResponse struct { + Error ErrorDetail `json:"error"` +} + +type ErrorDetail struct { + Code int `json:"code"` + Message string `json:"message"` + Detail string `json:"detail"` +} + +func Success(c *gin.Context, data interface{}) { + c.JSON(200, SuccessResponse{Data: data}) +} + +func Error(c *gin.Context, code int, message string, detail string) { + c.JSON(code, ErrorResponse{Error: ErrorDetail{Code: code, Message: message, Detail: detail}}) +}