Golang with echo for path param

mail@pastecode.io avatar
unknown
golang
6 months ago
3.2 kB
21
Indexable
Never
package b

import (
	"context"
	"encoding/json"
	"errors"
	"log"
	"net/http"
	"regexp"
	"strconv"

	"github.com/gorilla/mux"
	"github.com/labstack/echo"
)

func Build() *echo.Echo {
	e := echo.New()
	p := paymentRecordSrv{}

	e.GET("/payment",
		echo.WrapHandler(http.HandlerFunc(p.ShowPaymentList)),
		p.middlewareAuth)

	e.GET("/payment/:paymentID",
		detail,
		p.middlewareAuth)

	return e
}

func detail(ec echo.Context) error {
	type contextKey int

	const (
		varsKey contextKey = iota
	)

	param := ec.Param("paymentID")
	val := map[string]string{
		"paymentID": param,
	}
	req := ec.Request()
	ctx := req.Context()
	ctx = context.WithValue(ctx, varsKey, val)

	query := mux.Vars(req.WithContext(ctx))
	paymentIDStr, errEscape := EscapeSpecialCharacter(query["paymentID"])
	if errEscape != nil {
		return errors.New("value payment_id should be numeric")
	}

	_, err := strconv.ParseUint(paymentIDStr, 10, 64)
	if err != nil {
		return errors.New("value payment_id should be numeric")
	}

	return nil
}

func (q *paymentRecordSrv) middlewareAuth(next echo.HandlerFunc) echo.HandlerFunc {
	return func(ec echo.Context) error {
		req := ec.Request()

		ec.SetRequest(req)
		return next(ec)
	}
}

type PaymentService interface {
	ShowPaymentList(writer http.ResponseWriter, req *http.Request)

	ShowPaymentDetail(writer http.ResponseWriter, req *http.Request)
}

type paymentRecordSrv struct{}

func (paymentRecordSrv) ShowPaymentList(writer http.ResponseWriter, req *http.Request) {
	ToSuccessResponse(writer, nil, map[string]string{
		"message": "success",
	})
}

func (paymentRecordSrv) ShowPaymentDetail(writer http.ResponseWriter, req *http.Request) {
	query := mux.Vars(req)
	paymentIDStr, errEscape := EscapeSpecialCharacter(query["paymentID"])
	if errEscape != nil {
		return
	}

	_, err := strconv.ParseUint(paymentIDStr, 10, 64)
	if err != nil {
		return
	}

	return
}

type ProjectSuper struct {
	Rc         string      `json:"rc,omitempty"`
	Message    string      `json:"message,omitempty"`
	Pagination interface{} `json:"pagination,omitempty"`
	Data       interface{} `json:"data,omitempty"`
}

func NewProjectResponse(
	rc string,
	message string,
	pagination interface{},
	data interface{}) *ProjectSuper {
	return &ProjectSuper{
		Rc:         rc,
		Message:    message,
		Pagination: pagination,
		Data:       data,
	}
}

func ToSuccessResponse(writer http.ResponseWriter, pagination interface{}, data interface{}) {
	rc := "00"
	rcDesc := "Success"
	httpRes := 200
	ResponseWrite(
		writer,
		NewProjectResponse(rc, rcDesc, pagination, data),
		httpRes,
	)
}

func ResponseWrite(rw http.ResponseWriter, data interface{}, statusCode int) {
	responseByte, err := json.Marshal(data)
	rw.Header().Set("Content-type", "application/json")
	rw.WriteHeader(statusCode)

	if err != nil {
		log.Println("error during encode responseWrite", err)
	}

	_, err = rw.Write(responseByte)
}

func EscapeSpecialCharacter(string string) (string, error) {
	reg, err := regexp.Compile(`[!?;{}|<>%'=]`)
	if err != nil {
		return string, errors.New("value id should be just numeric")
	}

	newString := reg.ReplaceAllString(string, "")
	return newString, nil
}