From ef15af6cbd55b125ee62d5d670ee4ad28fad9db4 Mon Sep 17 00:00:00 2001 From: James Tombleson Date: Sun, 28 Apr 2024 11:40:19 -0700 Subject: [PATCH] cleaned up the article handler with new reponse models and moving to the repo structs --- internal/handler/v1/articles.go | 178 +++++++++++++------------------- 1 file changed, 70 insertions(+), 108 deletions(-) diff --git a/internal/handler/v1/articles.go b/internal/handler/v1/articles.go index 5703404..8bae404 100644 --- a/internal/handler/v1/articles.go +++ b/internal/handler/v1/articles.go @@ -4,186 +4,148 @@ import ( "net/http" "strconv" - "git.jamestombleson.com/jtom38/newsbot-api/internal/domain/models" - "github.com/google/uuid" + "git.jamestombleson.com/jtom38/newsbot-api/internal/domain" + "git.jamestombleson.com/jtom38/newsbot-api/internal/services" "github.com/labstack/echo/v4" ) -//func (s *Handler) GetArticleRouter() http.Handler { -// r := chi.NewRouter() -// -// r.Get("/", s.listArticles) -// r.Route("/{ID}", func(r chi.Router) { -// r.Get("/", s.getArticle) -// r.Get("/details", s.getArticleDetails) -// }) -// r.Get("/by/sourceid", s.ListArticlesBySourceId) -// -// return r -//} - -type ArticlesListResults struct { - ApiStatusModel - Payload []models.ArticleDto `json:"payload"` -} - -type ArticleGetResults struct { - ApiStatusModel - Payload models.ArticleDto `json:"payload"` -} - -type ArticleDetailsResult struct { - ApiStatusModel - Payload models.ArticleDetailsDto `json:"payload"` -} - // ListArticles // @Summary Lists the top 25 records ordering from newest to oldest. // @Produce application/json // @Param page query string false "page number" // @Tags Articles // @Router /articles [get] -// @Success 200 {object} ArticlesListResults "OK" +// @Success 200 {object} domain.ArticleResponse +// @Failure 400 {object} domain.BaseResponse +// @Failure 500 {object} domain.BaseResponse func (s *Handler) listArticles(c echo.Context) error { - p := ArticlesListResults{ - ApiStatusModel: ApiStatusModel{ - Message: "OK", - StatusCode: http.StatusOK, + resp := domain.ArticleResponse{ + BaseResponse: domain.BaseResponse{ + Message: ResponseMessageSuccess, }, } - queryPage := c.QueryParam("page") - - // if a page number was sent, process it - if len(queryPage) >= 1 { - page, err := strconv.Atoi(queryPage) - if err != nil { - return c.JSON(http.StatusBadRequest, err) - } - - res, err := s.dto.ListArticles(c.Request().Context(), 25, page) - if err != nil { - return c.JSON(http.StatusInternalServerError, err) - } - p.Payload = res - return c.JSON(http.StatusOK, p) - } else { - res, err := s.dto.ListArticles(c.Request().Context(), 25, 0) - if err != nil { - return c.JSON(http.StatusInternalServerError, err) - } - p.Payload = res - return c.JSON(http.StatusOK, p) + page, err := strconv.Atoi(c.QueryParam("page")) + if err != nil { + page = 0 } + + res, err := s.repo.Articles.ListByPage(c.Request().Context(), page, 25) + if err != nil { + s.WriteError(c, err, http.StatusInternalServerError) + } + + resp.Payload = services.ArticlesToDto(res) + return c.JSON(http.StatusOK, resp) } // GetArticle // @Summary Returns an article based on defined ID. -// @Param ID path string true "uuid" +// @Param ID path string true "int" // @Produce application/json // @Tags Articles // @Router /articles/{ID} [get] // @Success 200 {object} ArticleGetResults "OK" +// @Failure 400 {object} domain.BaseResponse +// @Failure 500 {object} domain.BaseResponse func (s *Handler) getArticle(c echo.Context) error { - p := ArticleGetResults{ - ApiStatusModel: ApiStatusModel{ - Message: "OK", - StatusCode: http.StatusOK, + p := domain.ArticleResponse{ + BaseResponse: domain.BaseResponse{ + Message: ResponseMessageSuccess, }, } id := c.Param("ID") - uuid, err := uuid.Parse(id) + idNumber, err := strconv.Atoi(id) if err != nil { - return c.JSON(http.StatusBadRequest, err) + s.WriteError(c, err, http.StatusBadRequest) } - res, err := s.dto.GetArticle(c.Request().Context(), uuid) + item, err := s.repo.Articles.GetById(c.Request().Context(), int64(idNumber)) if err != nil { return c.JSON(http.StatusInternalServerError, err) } - p.Payload = res + var dtos []domain.ArticleDto + dtos = append(dtos, services.ArticleToDto(item)) + p.Payload = dtos return c.JSON(http.StatusOK, p) } // GetArticleDetails // @Summary Returns an article and source based on defined ID. -// @Param ID path string true "uuid" +// @Param ID path string true "int" // @Produce application/json // @Tags Articles // @Router /articles/{ID}/details [get] // @Success 200 {object} ArticleDetailsResult "OK" +// @Failure 400 {object} domain.BaseResponse +// @Failure 500 {object} domain.BaseResponse func (s *Handler) getArticleDetails(c echo.Context) error { - p := ArticleDetailsResult{ - ApiStatusModel: ApiStatusModel{ - Message: "OK", - StatusCode: http.StatusOK, + p := domain.ArticleDetailResponse{ + BaseResponse: domain.BaseResponse{ + Message: ResponseMessageSuccess, + }, + Payload: domain.ArticleAndSourceModel{ + }, } - id := c.Param("ID") - uuid, err := uuid.Parse(id) + id, err := strconv.Atoi(c.Param("ID")) if err != nil { - return c.JSON(http.StatusBadRequest, err) + s.WriteError(c, err, http.StatusBadRequest) } - res, err := s.dto.GetArticleDetails(c.Request().Context(), uuid) + article, err := s.repo.Articles.GetById(c.Request().Context(), int64(id)) if err != nil { - return c.JSON(http.StatusInternalServerError, err) + s.WriteError(c, err, http.StatusInternalServerError) } - p.Payload = res + source, err := s.repo.Sources.GetById(c.Request().Context(), article.SourceID) + if err != nil { + s.WriteError(c, err, http.StatusInternalServerError) + } + + p.Payload.Article = services.ArticleToDto(article) + p.Payload.Source = services.SourceToDto(source) return c.JSON(http.StatusOK, p) } -// TODO add page support // ListArticlesBySourceID // @Summary Finds the articles based on the SourceID provided. Returns the top 25. -// @Param id query string true "Source ID UUID" +// @Param id query string true // @Param page query int false "Page to query" // @Produce application/json // @Tags Articles // @Router /articles/by/sourceid [get] // @Success 200 {object} ArticlesListResults "OK" +// @Failure 400 {object} domain.BaseResponse +// @Failure 500 {object} domain.BaseResponse func (s *Handler) ListArticlesBySourceId(c echo.Context) error { - p := ArticlesListResults{ - ApiStatusModel: ApiStatusModel{ - Message: "OK", - StatusCode: http.StatusOK, + p := domain.ArticleResponse{ + BaseResponse: domain.BaseResponse{ + Message: ResponseMessageSuccess, }, } - id := c.QueryParam("id") - - uuid, err := uuid.Parse(id) + id, err := strconv.Atoi(c.QueryParam("id")) if err != nil { - return c.JSON(http.StatusBadRequest, err) + s.WriteError(c, err, http.StatusBadRequest) } - // if a page number was sent, process it - if len(c.QueryParam("page")) >= 1 { - _page, err := strconv.Atoi(c.QueryParam("page")) - if err != nil { - return c.JSON(http.StatusBadRequest, err) - } - - res, err := s.dto.ListNewArticlesBySourceId(c.Request().Context(), uuid, 25, _page) - if err != nil { - return c.JSON(http.StatusInternalServerError, err) - } - - p.Payload = res - } else { - res, err := s.dto.ListNewArticlesBySourceId(c.Request().Context(), uuid, 25, 0) - if err != nil { - return c.JSON(http.StatusInternalServerError, err) - } - - p.Payload = res + // if the page number is missing, default to 0 + _page, err := strconv.Atoi(c.QueryParam("page")) + if err != nil { + _page = 0 } + + items, err := s.repo.Articles.ListBySource(c.Request().Context(), _page, 25, id, "") + if err != nil { + return c.JSON(http.StatusInternalServerError, err) + } + + p.Payload = services.ArticlesToDto(items) return c.JSON(http.StatusOK, p) - }