From 1436db65191ca41bf210913731c92feb14549be5 Mon Sep 17 00:00:00 2001 From: Dumindu Madunuwan Date: Sun, 30 Aug 2026 17:32:15 +0800 Subject: [PATCH] Remove form layer --- README.md | 9 +++------ app/book/form.go | 35 +++++++++++++++++++++++++++++++++++ app/book/form_util.go | 28 ---------------------------- app/book/handler.go | 23 +++++++++++------------ form/book.go | 11 ----------- openapi.yaml | 6 +++--- 6 files changed, 52 insertions(+), 60 deletions(-) create mode 100644 app/book/form.go delete mode 100644 app/book/form_util.go delete mode 100644 form/book.go diff --git a/README.md b/README.md index 29b8d2e..94ae6c1 100644 --- a/README.md +++ b/README.md @@ -37,9 +37,9 @@ type Handler struct { func (h *Handler) Register(r chi.Router) { r.Get("/", h.list) - r.With(m.Validate[form.BookForm](h.validator)).Post("/", h.create) + r.With(m.Validate[Form](h.validator)).Post("/", h.create) r.Get("/{id}", h.read) - r.With(m.Validate[form.BookForm](h.validator)).Put("/{id}", h.update) + r.With(m.Validate[Form](h.validator)).Put("/{id}", h.update) r.Delete("/{id}", h.delete) } @@ -190,14 +190,11 @@ app-1 | {"level":"info","request_id":"d5mqjmhqvtmc73foh3dg","received_time":"20 │ └── migrations │ └── 00001_create_books_table.sql │ -├── form # 💡Form validation middleware rely on this and pkg folder only -│ └── book.go -│ ├── app │ ├── book │ │ ├── bookrepo # 💡generated with gorm-cli via the interface in book/repository.go │ │ │ └── repository.go -│ │ ├── form_util.go +│ │ ├── form.go # 💡validate via Go generics based form validation middleware │ │ ├── handler.go │ │ └── repository.go │ └── router diff --git a/app/book/form.go b/app/book/form.go new file mode 100644 index 0000000..c537391 --- /dev/null +++ b/app/book/form.go @@ -0,0 +1,35 @@ +package book + +import ( + "time" + + "github.com/google/uuid" + + "myapp/model" +) + +type Form struct { + Title string `json:"title" validate:"required,max=255"` + PublishedDate string `json:"published_date" validate:"required,datetime=2006-01-02"` + Description string `json:"description"` + ImageURL string `json:"image_url" validate:"url"` + Status string `json:"status" validate:"required,oneof=pending verified"` +} + +func (f *Form) ToCreateModel() *model.Book { + return f.ToUpdateModel(uuid.New()) +} + +func (f *Form) ToUpdateModel(id uuid.UUID) *model.Book { + pubDate, _ := time.Parse("2006-01-02", f.PublishedDate) + status, _ := model.ParseBookStatus(f.Status) + + return &model.Book{ + ID: id, + PublishedDate: model.CivilDate(pubDate), + Title: f.Title, + ImageURL: f.ImageURL, + Description: f.Description, + Status: *status, + } +} diff --git a/app/book/form_util.go b/app/book/form_util.go deleted file mode 100644 index efdee82..0000000 --- a/app/book/form_util.go +++ /dev/null @@ -1,28 +0,0 @@ -package book - -import ( - "time" - - "github.com/google/uuid" - - "myapp/form" - "myapp/model" -) - -func createFormToModel(f *form.BookForm) *model.Book { - return updateFormToModel(f, uuid.New()) -} - -func updateFormToModel(f *form.BookForm, id uuid.UUID) *model.Book { - pubDate, _ := time.Parse("2006-01-02", f.PublishedDate) - status, _ := model.ParseBookStatus(f.Status) - - return &model.Book{ - ID: id, - PublishedDate: model.CivilDate(pubDate), - Title: f.Title, - ImageURL: f.ImageURL, - Description: f.Description, - Status: *status, - } -} diff --git a/app/book/handler.go b/app/book/handler.go index 78928c5..cfc8140 100644 --- a/app/book/handler.go +++ b/app/book/handler.go @@ -12,7 +12,6 @@ import ( "gorm.io/gorm" "myapp/app/book/bookrepo" - "myapp/form" "myapp/model" "myapp/pkg/ctxutil" e "myapp/pkg/errors" @@ -34,9 +33,9 @@ func New(validator *validator.Validate, db *gorm.DB) *Handler { func (h *Handler) Register(r chi.Router) { r.Get("/", h.list) - r.With(m.Validate[form.BookForm](h.validator)).Post("/", h.create) + r.With(m.Validate[Form](h.validator)).Post("/", h.create) r.Get("/{id}", h.read) - r.With(m.Validate[form.BookForm](h.validator)).Put("/{id}", h.update) + r.With(m.Validate[Form](h.validator)).Put("/{id}", h.update) r.Delete("/{id}", h.delete) } @@ -83,7 +82,7 @@ func (h *Handler) list(w http.ResponseWriter, r *http.Request) { // @tags books // @accept json // @produce json -// @param body body form.BookForm true "Book form" +// @param body body Form true "Book form" // @success 201 {object} model.Book // @failure 400 {object} e.Error // @failure 422 {object} e.Errors @@ -93,14 +92,14 @@ func (h *Handler) create(w http.ResponseWriter, r *http.Request) { ctx := r.Context() logger := hlog.FromRequest(r) - ctxForm, ok := ctxutil.ValidatedForm[form.BookForm](ctx) + ctxForm, ok := ctxutil.ValidatedForm[Form](ctx) if !ok { - logger.Error().Msg(form.LogErrCTXValidatedFormNotFound) + logger.Error().Msg("validated form not found") e.ServerError(w, e.RespValidatedFormNotFound) return } - book, err := h.bookRepo.CreateBook(ctx, createFormToModel(&ctxForm)) + book, err := h.bookRepo.CreateBook(ctx, ctxForm.ToCreateModel()) if err != nil { logger.Error().Err(err).Msg("") e.ServerError(w, e.RespDBDataInsertFailure) @@ -166,8 +165,8 @@ func (h *Handler) read(w http.ResponseWriter, r *http.Request) { // @tags books // @accept json // @produce json -// @param id path string true "Book ID" -// @param body body form.BookForm true "Book form" +// @param id path string true "Book ID" +// @param body body Form true "Book form" // @success 200 {object} model.Book // @failure 400 {object} e.Error // @failure 404 @@ -184,14 +183,14 @@ func (h *Handler) update(w http.ResponseWriter, r *http.Request) { return } - ctxForm, ok := ctxutil.ValidatedForm[form.BookForm](ctx) + ctxForm, ok := ctxutil.ValidatedForm[Form](ctx) if !ok { - logger.Error().Msg(form.LogErrCTXValidatedFormNotFound) + logger.Error().Msg("validated form not found") e.ServerError(w, e.RespValidatedFormNotFound) return } - book, err := h.bookRepo.UpdateBook(ctx, updateFormToModel(&ctxForm, id)) + book, err := h.bookRepo.UpdateBook(ctx, ctxForm.ToUpdateModel(id)) if err != nil { logger.Error().Err(err).Msg("") e.ServerError(w, e.RespDBDataUpdateFailure) diff --git a/form/book.go b/form/book.go deleted file mode 100644 index 8ad0723..0000000 --- a/form/book.go +++ /dev/null @@ -1,11 +0,0 @@ -package form - -const LogErrCTXValidatedFormNotFound = "context validated form not found" - -type BookForm struct { - Title string `json:"title" validate:"required,max=255"` - PublishedDate string `json:"published_date" validate:"required,datetime=2006-01-02"` - Description string `json:"description"` - ImageURL string `json:"image_url" validate:"url"` - Status string `json:"status" validate:"required,oneof=pending verified"` -} diff --git a/openapi.yaml b/openapi.yaml index 93f00fb..8228216 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1,5 +1,5 @@ definitions: - form.BookForm: + app_book.Form: properties: description: type: string @@ -118,7 +118,7 @@ paths: name: body required: true schema: - $ref: '#/definitions/form.BookForm' + $ref: '#/definitions/app_book.Form' produces: - application/json responses: @@ -215,7 +215,7 @@ paths: name: body required: true schema: - $ref: '#/definitions/form.BookForm' + $ref: '#/definitions/app_book.Form' produces: - application/json responses: