Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to implement endpoints for specific content-types #1584

Open
3 tasks done
eloo opened this issue Jun 4, 2020 · 5 comments
Open
3 tasks done

How to implement endpoints for specific content-types #1584

eloo opened this issue Jun 4, 2020 · 5 comments

Comments

@eloo
Copy link

eloo commented Jun 4, 2020

Issue Description

How to implement endpoints for specific content-types

Checklist

  • Dependencies installed
  • No typos
  • Searched existing issues and docs

Expected behaviour

I've have an PATCH endpoint which only accepts requests with content-type application/merge-patch+json

Actual behaviour

Not sure how to implement it

Details

I'm currently trying to create an endpoint which supports the https://tools.ietf.org/html/rfc7396 standard for patching resources.
But im struggling right now how to implement the specific content-type i want to accept.
So every request without the content-type to be set to application/merge-patch+json should be rejected with at 415.

My two ideas are the following:

  • In the handler function i just check the header manually and reject it with 415 if the content-type does not match
    or what i've found here so far
  • Create custom binder to bind the data which only accepts the specific content-type

I guess the second approach is the better but i'm not sure if there is maybe another solution or what should be prefered?

Thanks

@mymtw
Copy link

mymtw commented Jun 10, 2020

think that you should check both

@stale
Copy link

stale bot commented Aug 9, 2020

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the wontfix label Aug 9, 2020
@eloo
Copy link
Author

eloo commented Aug 10, 2020

for the record:
i'm now using the following snippet for this use-case:

import (
	"encoding/json"
	"fmt"
	"net/http"
	"strings"

	"github.com/labstack/echo/v4"
)

type MergeJsonBinder struct{}

// Bind implements the `Binder#Bind` function.
func (b *MergeJsonBinder) Bind(i interface{}, c echo.Context) (err error) {
	req := c.Request()

	names := c.ParamNames()
	values := c.ParamValues()
	params := map[string][]string{}
	for i, name := range names {
		params[name] = []string{values[i]}
	}
	if req.ContentLength == 0 {
		return
	}
	ctype := req.Header.Get(echo.HeaderContentType)
	switch {
	case strings.HasPrefix(ctype, MIMEApplicationMergePatchJSON):
		if err = json.NewDecoder(req.Body).Decode(i); err != nil {
			if ute, ok := err.(*json.UnmarshalTypeError); ok {
				return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Unmarshal type error: expected=%v, got=%v, field=%v, offset=%v", ute.Type, ute.Value, ute.Field, ute.Offset)).SetInternal(err)
			} else if se, ok := err.(*json.SyntaxError); ok {
				return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Syntax error: offset=%v, error=%v", se.Offset, se.Error())).SetInternal(err)
			}
			return echo.NewHTTPError(http.StatusBadRequest, err.Error()).SetInternal(err)
		}
	default:
		return echo.ErrUnsupportedMediaType
	}
	return
}

and something like this in the endpoint handler

mergeJsonBinder := MergeJsonBinder{}
		var body map[string]interface{}
		err := mergeJsonBinder.Bind(&body, c)
		if err != nil {
			return err
		}

maybe this can be adapted and added as an example to the documention?

@stale
Copy link

stale bot commented Nov 7, 2020

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the wontfix label Nov 7, 2020
@lyda
Copy link

lyda commented Jan 6, 2024

I submitted PR #2572 which would fix this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants