Skip to content

Parameters converter #3

@mdouchement

Description

@mdouchement
  • logger
...

params, err := json.Marshal(c.Get("echo_request_params"))
if err != nil {
	params = []byte("Ignored error during parameters parsing")
}
if len(params) == 0 {
	params = []byte{}
}

...
  • params_converter.go
package middlewares

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"strings"

	"github.com/labstack/echo"
)

// ParamsConverter instances a ParamsConverter middleware that will convert JSON body parameters into gin.Params
// Must be used after logger middleware:
//   engine.Use(middlewares.Logger())
//   engine.Use(middlewares.ParamsConverter())
func ParamsConverter() echo.MiddlewareFunc {
	return func(next echo.HandlerFunc) echo.HandlerFunc {
		return func(c echo.Context) (err error) {
			// Handles URL queries
			params := make(map[string]interface{}, len(c.ParamNames()))
			for _, pname := range c.ParamNames() {
				params[pname] = c.Param(pname)
			}
			queries := c.QueryParams()
			for qname := range queries {
				params[qname] = queries.Get(qname)
			}

			// Pre-handles JSON body parameters
			body := &bytes.Buffer{}
			if strings.Contains(c.Request().Header.Get(echo.HeaderContentType), echo.MIMEApplicationJSON) && c.Request().Header.Get(echo.HeaderContentLength) != "" {
				c.Request().Body = newTeeReadCloser(c.Request().Body, body)
			}

			if err = next(c); err != nil {
				c.Error(err)
			}

			// Handles JSON body parameters
			if body.Len() > 0 {
				if err := json.Unmarshal(body.Bytes(), &params); err != nil {
					return fmt.Errorf("ParamsConverter: %s", err.Error())
				}
			}
			c.Set("echo_request_params", params)

			return
		}
	}
}

// http.Request.Body interceptor

type teeReadCloser struct {
	r io.Reader
	w io.Writer
	c io.Closer
}

func newTeeReadCloser(r io.ReadCloser, w io.Writer) io.ReadCloser {
	return &teeReadCloser{io.TeeReader(r, w), w, r}
}

// Read implements io.Reader
func (t *teeReadCloser) Read(b []byte) (int, error) {
	return t.r.Read(b)
}

// Close attempts to close the reader and write. It returns an error if both
// failed to Close.
func (t *teeReadCloser) Close() error {
	return t.c.Close()
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions