func categoriesHandlerWithProxyMode()

in categories.go [35:99]


func categoriesHandlerWithProxyMode(logger *zap.Logger, indexer Indexer, proxyMode *proxymode.ProxyMode, cacheTime time.Duration) func(w http.ResponseWriter, r *http.Request) {
	return func(w http.ResponseWriter, r *http.Request) {
		logger := logger.With(apmzap.TraceContext(r.Context())...)

		query := r.URL.Query()

		filter, err := newCategoriesFilterFromQuery(query)
		if err != nil {
			badRequest(w, err.Error())
			return
		}

		includePolicyTemplates := false
		if v := query.Get("include_policy_templates"); v != "" {
			includePolicyTemplates, err = strconv.ParseBool(v)
			if err != nil {
				badRequest(w, fmt.Sprintf("invalid 'include_policy_templates' query param: '%s'", v))
				return
			}
		}

		opts := packages.GetOptions{
			Filter: filter,
		}
		pkgs, err := indexer.Get(r.Context(), &opts)
		if err != nil {
			notFoundError(w, err)
			return
		}
		categories := getCategories(r.Context(), pkgs, includePolicyTemplates)

		if proxyMode.Enabled() {
			proxiedCategories, err := proxyMode.Categories(r)
			if err != nil {
				logger.Error("proxy mode: categories failed", zap.Error(err))
				http.Error(w, "internal server error", http.StatusInternalServerError)
				return
			}

			for _, category := range proxiedCategories {
				if _, ok := categories[category.Id]; !ok {
					categories[category.Id] = &packages.Category{
						Id:          category.Id,
						Title:       category.Title,
						Count:       category.Count,
						ParentId:    category.ParentId,
						ParentTitle: category.ParentTitle,
					}
				} else {
					categories[category.Id].Count += category.Count
				}
			}
		}

		data, err := getCategoriesOutput(r.Context(), categories)
		if err != nil {
			notFoundError(w, err)
			return
		}

		cacheHeaders(w, cacheTime)
		jsonHeader(w)
		w.Write(data)
	}
}