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

Batch queries #44

Open
ArturHarutunyan opened this issue Jan 14, 2023 · 0 comments
Open

Batch queries #44

ArturHarutunyan opened this issue Jan 14, 2023 · 0 comments
Assignees
Labels
enhancement New feature or request

Comments

@ArturHarutunyan
Copy link

now is not possible to do batch queries. I suggest just small changes to give that possibility.
that functionality is actively used by Apollo for optimizing the query execution time.
the suggested changes are attached

        // router.go line 95
        gqlRequests, err := h.unmarshalHTTPRequest(r)
	if err != nil {
		h.logger.Debug("can not unmarshal graphql request from http request", zap.Error(err))
		reporter.error = writeResponseErrors(err, w)

		return
	}
	n := r.Context().Value(nextHandlerCtxKey).(caddyhttp.Handler)

	for _, gqlRequest := range *gqlRequests {
		if err = h.validateGraphqlRequest(&gqlRequest); err != nil {
			reporter.error = writeResponseErrors(err, w)

			return
		}

		h.addMetricsBeginRequest(&gqlRequest)
		defer func(startedAt time.Time) {
			h.addMetricsEndRequest(&gqlRequest, time.Since(startedAt))
		}(time.Now())

		if h.Caching != nil {
			cachingRequest := newCachingRequest(r, h.schemaDocument, h.schema, &gqlRequest)
			reverse := caddyhttp.HandlerFunc(func(w http.ResponseWriter, r *http.Request) error {
				return h.ReverseProxy.ServeHTTP(w, r, n)
			})

			if err = h.Caching.HandleRequest(w, cachingRequest, reverse); err != nil {
				reporter.error = writeResponseErrors(err, w)

				return
			}

			return
		}
	}

	reporter.error = h.ReverseProxy.ServeHTTP(w, r, n)
}

func (h *Handler) unmarshalHTTPRequest(r *http.Request) (*[]graphql.Request, error) {
	gqlRequests := make([]graphql.Request, 0)
	rawBody, _ := ioutil.ReadAll(r.Body)
	r.Body = ioutil.NopCloser(bytes.NewBuffer(rawBody))
	copyHTTPRequest, err := http.NewRequest(r.Method, r.URL.String(), ioutil.NopCloser(bytes.NewBuffer(rawBody))) // nolint:noctx
	if err != nil {
		return nil, err
	}

	requestBytes, err := ioutil.ReadAll(copyHTTPRequest.Body)
	if err != nil {
		return nil, err
	}

	if len(requestBytes) == 0 {
		return nil, graphql.ErrEmptyRequest
	}

	if err = json.Unmarshal(requestBytes, &gqlRequests); err != nil {
		var gqlRequest graphql.Request
		if e := json.Unmarshal(requestBytes, &gqlRequest); e != nil {
			return nil, e
		}
		gqlRequests = append(gqlRequests, gqlRequest)
	}
	for index, request := range gqlRequests {
		if err = normalizeGraphqlRequest(h.schema, &request); err != nil {
			return nil, err
		}
		gqlRequests[index] = request
	}

	return &gqlRequests, nil
}

@vuongxuongminh vuongxuongminh added the enhancement New feature or request label Jan 18, 2023
@vuongxuongminh vuongxuongminh self-assigned this Jan 18, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants