libopenapi-validator icon indicating copy to clipboard operation
libopenapi-validator copied to clipboard

fasthttp (Fiber v2) Request Validation Support

Open tommynanny opened this issue 8 months ago • 1 comments

Thank you for your work on this project.

We’re using libopenapi-validator in a Go project with Fiber v2, which is based on fasthttp.

I have a few questions:

  • Does libopenapi-validator support native validation of fasthttp (or Fiber) requests, or is there an official/community adapter already available?
  • If not, are there any recommended practices for this use case?
  • If neither exist, would you consider adding native fasthttp support as a future feature?

Currently, we’re using a self-written middleware adapter that translates the Fiber request into a standard http.Request for validation (see code below). While this works, manual conversion can cause some inefficiency. It would be really helpful to have native fasthttp support so we wouldn’t incur this overhead and could use the validator more efficiently with high-performance frameworks. Here’s our current implementation:

func ToHttpRequest(ctx *fasthttp.RequestCtx) (*http.Request, error) {
	// convert method
	method := string(ctx.Method())
	// convert URI
	uri := ctx.Request.URI()
	urlStr := uri.String()
	parsedURL, err := url.Parse(urlStr)
	if err != nil {
		return nil, fmt.Errorf("failed to parse URL: %w", err)
	}
	// convert headers
	headers := make(http.Header)
	ctx.Request.Header.VisitAll(func(key, value []byte) {
		headers.Set(string(key), string(value))
	})
	// convert body
	body := ctx.Request.Body()
	bodyReader := io.NopCloser(bytes.NewReader(body))
	return &http.Request{
		Method: method,
		URL:    parsedURL,
		Header: headers,
		Body:   bodyReader,
	}, nil
}

func (oasf *OasFile) ValidationMiddleware() fiber.Handler {
    return func(c *fiber.Ctx) error {
        httpReq, err := utils.ToHttpRequest(c.Context())
        if err != nil {
            return err
        }
        if oasf.validator == nil {
            return errors.New("validator is not initialized")
        }
        v := *oasf.validator
        requestValid, validationErrors := v.ValidateHttpRequest(httpReq)
        results := []error{}
        if !requestValid {
            for i := range validationErrors {
                results = append(results, buildValidationErrors(validationErrors[i].SchemaValidationErrors)...)
            }
        }
        if len(results) > 0 {
            e := dto.NewError(results...).WithCode(http.StatusBadRequest)
            return e
        }
        return c.Next()
    }
}

It works for us so far, but may not cover all fasthttp/Fiber edge cases and hasn’t been deeply tested. If you have any feedback, suggestions to improve this approach, or know of a better solution, your input would be greatly appreciated!

tommynanny avatar Jun 05 '25 12:06 tommynanny

Hi, Great to hear you're finding success.

This is the first request for fiber support, so it can absolutely be on the roadmap. There isn't support for it yes (as you have discovered) but absolutely could be.

The only snag on this is that it will most likely have to be a community solution. I don't use either frameworks in my toolchain yet and I only build what I need, when I need it. So until that bridge comes my way, I won't be building it out.

But I love the idea and your workaround should also be suitable for other folks in the community who need this.

Fully open to PRs, all are welcome.

daveshanley avatar Jun 05 '25 13:06 daveshanley