iris/_examples/database/mysql/api/product_handler.go
Gerasimos (Makis) Maropoulos ed45c77be5 reorganization of _examples and add some new examples such as iris+groupcache+mysql+docker
Former-commit-id: ed635ee95de7160cde11eaabc0c1dcb0e460a620
2020-06-07 15:26:06 +03:00

174 lines
4.2 KiB
Go

package api
import (
"time"
"myapp/cache"
"myapp/entity"
"myapp/service"
"myapp/sql"
"github.com/kataras/iris/v12"
)
// ProductHandler is the http mux for products.
type ProductHandler struct {
service *service.ProductService
cache *cache.Cache
}
// NewProductHandler returns the main controller for the products API.
func NewProductHandler(service *service.ProductService) *ProductHandler {
return &ProductHandler{
service: service,
cache: cache.New(service, "products", time.Minute),
}
}
// GetByID fetches a single record from the database and sends it to the client.
// Method: GET.
func (h *ProductHandler) GetByID(ctx iris.Context) {
id := ctx.Params().GetString("id")
var product []byte
err := h.cache.GetByID(ctx.Request().Context(), id, &product)
if err != nil {
if err == sql.ErrNoRows {
writeEntityNotFound(ctx)
return
}
debugf("ProductHandler.GetByID(id=%v): %v", id, err)
writeInternalServerError(ctx)
return
}
ctx.ContentType("application/json")
ctx.Write(product)
// ^ Could use our simple `noCache` or implement a Cache-Control (see kataras/iris/cache for that)
// but let's keep it simple.
}
// List lists a set of records from the database.
// Method: GET.
func (h *ProductHandler) List(ctx iris.Context) {
key := ctx.Request().URL.RawQuery
products := []byte("[]")
err := h.cache.List(ctx.Request().Context(), key, &products)
if err != nil && err != sql.ErrNoRows {
debugf("ProductHandler.List(DB) (%s): %v",
key, err)
writeInternalServerError(ctx)
return
}
ctx.ContentType("application/json")
ctx.Write(products)
}
// Create adds a record to the database.
// Method: POST.
func (h *ProductHandler) Create(ctx iris.Context) {
var product entity.Product
if err := ctx.ReadJSON(&product); err != nil {
return
}
id, err := h.service.Insert(ctx.Request().Context(), product)
if err != nil {
if err == sql.ErrUnprocessable {
ctx.StopWithJSON(iris.StatusUnprocessableEntity, newError(iris.StatusUnprocessableEntity, ctx.Request().Method, ctx.Path(), "required fields are missing"))
return
}
debugf("ProductHandler.Create(DB): %v", err)
writeInternalServerError(ctx)
return
}
// Send 201 with body of {"id":$last_inserted_id"}.
ctx.StatusCode(iris.StatusCreated)
ctx.JSON(iris.Map{product.PrimaryKey(): id})
}
// Update performs a full-update of a record in the database.
// Method: PUT.
func (h *ProductHandler) Update(ctx iris.Context) {
var product entity.Product
if err := ctx.ReadJSON(&product); err != nil {
return
}
affected, err := h.service.Update(ctx.Request().Context(), product)
if err != nil {
if err == sql.ErrUnprocessable {
ctx.StopWithJSON(iris.StatusUnprocessableEntity, newError(iris.StatusUnprocessableEntity, ctx.Request().Method, ctx.Path(), "required fields are missing"))
return
}
debugf("ProductHandler.Update(DB): %v", err)
writeInternalServerError(ctx)
return
}
status := iris.StatusOK
if affected == 0 {
status = iris.StatusNotModified
}
ctx.StatusCode(status)
}
// PartialUpdate is the handler for partially update one or more fields of the record.
// Method: PATCH.
func (h *ProductHandler) PartialUpdate(ctx iris.Context) {
id := ctx.Params().GetInt64Default("id", 0)
var attrs map[string]interface{}
if err := ctx.ReadJSON(&attrs); err != nil {
return
}
affected, err := h.service.PartialUpdate(ctx.Request().Context(), id, attrs)
if err != nil {
if err == sql.ErrUnprocessable {
ctx.StopWithJSON(iris.StatusUnprocessableEntity, newError(iris.StatusUnprocessableEntity, ctx.Request().Method, ctx.Path(), "unsupported value(s)"))
return
}
debugf("ProductHandler.PartialUpdate(DB): %v", err)
writeInternalServerError(ctx)
return
}
status := iris.StatusOK
if affected == 0 {
status = iris.StatusNotModified
}
ctx.StatusCode(status)
}
// Delete removes a record from the database.
// Method: DELETE.
func (h *ProductHandler) Delete(ctx iris.Context) {
id := ctx.Params().GetInt64Default("id", 0)
affected, err := h.service.DeleteByID(ctx.Request().Context(), id)
if err != nil {
debugf("ProductHandler.Delete(DB): %v", err)
writeInternalServerError(ctx)
return
}
status := iris.StatusOK // StatusNoContent
if affected == 0 {
status = iris.StatusNotModified
}
ctx.StatusCode(status)
}