ServeHTTP handles GraphQL queries and mutations that get resolved via GraphQL->Dgraph->GraphQL. It writes a valid GraphQL JSON response to w.
(w http.ResponseWriter, r *http.Request)
| 221 | // via GraphQL->Dgraph->GraphQL. It writes a valid GraphQL JSON response |
| 222 | // to w. |
| 223 | func (gh *graphqlHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { |
| 224 | ctx, span := trace.StartSpan(r.Context(), "handler") |
| 225 | defer span.End() |
| 226 | |
| 227 | ns, _ := strconv.ParseUint(r.Header.Get("resolver"), 10, 64) |
| 228 | glog.V(2).Infof("namespace: %d. Got GraphQL request over HTTP.", ns) |
| 229 | if err := gh.isValid(ns); err != nil { |
| 230 | glog.Errorf("namespace: %d. graphqlHandler not initialised: %s", ns, err) |
| 231 | WriteErrorResponse(w, r, errors.New(resolve.ErrInternal)) |
| 232 | return |
| 233 | } |
| 234 | |
| 235 | gh.resolverMux.RLock() |
| 236 | resolver := gh.resolver[ns] |
| 237 | gh.resolverMux.RUnlock() |
| 238 | |
| 239 | addDynamicHeaders(resolver, r.Header.Get("Origin"), w) |
| 240 | if r.Method == http.MethodOptions { |
| 241 | // for OPTIONS, we only need to send the headers |
| 242 | return |
| 243 | } |
| 244 | |
| 245 | // Pass in PoorMan's auth, ACL and IP information if present. |
| 246 | ctx = x.AttachAccessJwt(ctx, r) |
| 247 | ctx = x.AttachRemoteIP(ctx, r) |
| 248 | ctx = x.AttachAuthToken(ctx, r) |
| 249 | ctx = x.AttachJWTNamespace(ctx) |
| 250 | |
| 251 | var res *schema.Response |
| 252 | gqlReq, err := getRequest(r) |
| 253 | |
| 254 | if err != nil { |
| 255 | WriteErrorResponse(w, r, err) |
| 256 | return |
| 257 | } |
| 258 | |
| 259 | if err = edgraph.ProcessPersistedQuery(ctx, gqlReq); err != nil { |
| 260 | WriteErrorResponse(w, r, err) |
| 261 | return |
| 262 | } |
| 263 | |
| 264 | res = resolver.Resolve(ctx, gqlReq) |
| 265 | write(w, res, strings.Contains(r.Header.Get("Accept-Encoding"), "gzip")) |
| 266 | } |
| 267 | |
| 268 | func (gh *graphqlHandler) isValid(namespace uint64) error { |
| 269 | gh.resolverMux.RLock() |