Files
agenda-web-go/internal/handler/contact_handler.go

199 lines
5.0 KiB
Go

package handler
import (
"encoding/json"
"net/http"
"strconv"
"gitea.gabilandia.com/gabdlr/agenda-web-go/internal/models"
"gitea.gabilandia.com/gabdlr/agenda-web-go/internal/repository"
)
type ContactHandler struct {
repository repository.Repository[models.Contact]
}
const required_field = "is required"
const invalid_id = "Invalid ID"
func HandleContacts(mux *http.ServeMux, repo repository.Repository[models.Contact]) {
ch := &ContactHandler{repository: repo}
routes := []Route{
{"GET /contacts", ch.getAll},
{"GET /contacts/{id}", ch.getByID},
{"POST /contacts", ch.create},
{"PUT /contacts/{id}", ch.update},
{"DELETE /contacts/{id}", ch.delete},
}
NewBaseHandler(mux, routes)
}
// GetAll godoc
// @Summary Get all contacts
// @Description Get a list of all contacts
// @Tags contacts
// @Accept json
// @Produce json
// @Success 200 {object} APIResponse{data=[]models.Contact}
// @Failure 500 {object} APIResponse
// @Router /contacts [get]
func (h *ContactHandler) getAll(w http.ResponseWriter, r *http.Request) {
contacts, err := h.repository.GetAll()
if err != nil {
InternalError(w, err)
return
}
JSONSuccess(w, contacts, "Contact list retrieved successfully", http.StatusOK)
}
// GetByID godoc
// @Summary Get a contact by ID
// @Description Get a single contact by its ID
// @Tags contacts
// @Accept json
// @Produce json
// @Param id path int true "Contact ID"
// @Success 200 {object} APIResponse{data=models.Contact}
// @Failure 400 {object} APIResponse
// @Failure 404 {object} APIResponse
// @Failure 500 {object} APIResponse
// @Router /contacts/{id} [get]
func (h *ContactHandler) getByID(w http.ResponseWriter, r *http.Request) {
id, err := strconv.Atoi(r.PathValue("id"))
if err != nil {
BadRequest(w, ErrInvalidFormat, invalid_id)
return
}
contact, err := h.repository.GetByID(id)
if err != nil {
InternalError(w, err)
return
}
if contact == nil {
NotFound(w, ErrNotFound, "Contact not found")
return
}
JSONSuccess(w, contact, "Contact retrieved successfully", http.StatusOK)
}
// Create godoc
// @Summary Create a new contact
// @Description Create a new contact with the provided data
// @Tags contacts
// @Accept json
// @Produce json
// @Param contact body models.Contact true "Contact object"
// @Success 201 {object} APIResponse{data=models.Contact}
// @Failure 400 {object} APIResponse
// @Failure 500 {object} APIResponse
// @Router /contacts [post]
func (h *ContactHandler) create(w http.ResponseWriter, r *http.Request) {
var contact models.Contact
if err := json.NewDecoder(r.Body).Decode(&contact); err != nil {
BadRequest(w, ErrInvalidJSON, "Error parsing the contact")
return
}
if contact.Name == "" {
err := ErrMissingRequired
err.Field = "name"
BadRequest(w, err, RequiredFieldErr("name"))
return
}
if contact.Company == "" {
err := ErrMissingRequired
err.Field = "company"
BadRequest(w, err, RequiredFieldErr("company"))
return
}
if contact.Phone == "" {
err := ErrMissingRequired
err.Field = "phone"
BadRequest(w, err, RequiredFieldErr("phone"))
return
}
id, err := h.repository.Create(&contact)
if err != nil {
InternalError(w, err)
return
}
contact.ID = int(id)
JSONSuccess(w, contact, "Contact created successfully", http.StatusCreated)
}
// Update godoc
// @Summary Update a contact
// @Description Update an existing contact by ID
// @Tags contacts
// @Accept json
// @Produce json
// @Param id path int true "Contact ID"
// @Param contact body models.Contact true "Contact object"
// @Success 200 {object} APIResponse
// @Failure 400 {object} APIResponse
// @Failure 404 {object} APIResponse
// @Failure 500 {object} APIResponse
// @Router /contacts/{id} [put]
func (h *ContactHandler) update(w http.ResponseWriter, r *http.Request) {
id, err := strconv.Atoi(r.PathValue("id"))
if err != nil {
BadRequest(w, ErrInvalidFormat, invalid_id)
return
}
var contact models.Contact
if err := json.NewDecoder(r.Body).Decode(&contact); err != nil {
BadRequest(w, ErrInvalidJSON, "Error parsing the contact")
return
}
contact.ID = id
updateErr := h.repository.Update(&contact)
if updateErr != nil {
InternalError(w, updateErr)
return
}
JSONSuccess(w, nil, "Contact updated successfully", http.StatusOK)
}
// Delete godoc
// @Summary Delete a contact
// @Description Delete a contact by ID
// @Tags contacts
// @Accept json
// @Produce json
// @Param id path int true "Contact ID"
// @Success 200 {object} APIResponse
// @Failure 400 {object} APIResponse
// @Failure 404 {object} APIResponse
// @Failure 500 {object} APIResponse
// @Router /contacts/{id} [delete]
func (h *ContactHandler) delete(w http.ResponseWriter, r *http.Request) {
id, err := strconv.Atoi(r.PathValue("id"))
if err != nil {
BadRequest(w, ErrInvalidFormat, invalid_id)
return
}
rowsAffected, err := h.repository.Delete(id)
if err != nil {
InternalError(w, err)
return
}
if rowsAffected == 0 {
BadRequest(w, ErrNotFound, "Contact not found")
return
}
JSONSuccess(w, nil, "Contact deleted successfully", http.StatusOK)
}