1

我正在使用最后一个可用的 lacinia 版本:“0.36.0-alpha-3”和 Luminus (Ring+reitit),但这个版本要求一个特定的标题:

$ curl 'http://localhost:3000/api/graphql' -X POST --data "{test_by_id(id: 5) { title } }" -H 'Content-Type: application/graphql'

该请求可以正常工作,但如果没有“'Content-Type: application/graphql'”,该请求将无法正常工作。所以我需要定义我的重新图形初始化向量,如:

  [::re-graph/init
    {:ws-url                  nil 
     :http-url                "http://localhost:3000/api/graphql"
     :http-parameters         {:with-credentials? false
                               :headers {"Content-Type" "application/graphql"}
                               }
     :ws-reconnect-timeout    nil
     :resume-subscriptions?   false   
     :connection-init-payload {}}]

但是放置该标题会使重新图形无法正常工作:

{"errors":[{"message":"Failed to parse GraphQL query.","extensions":{"errors":[{"locations":[{"line":1,"column":null}],"message":"mismatched input '\"query\"' expecting {'query', 'mutation', 'subscription', 

看起来 re-graph 使用“application/json”标头发送和接收数据,因此 lacinia 要求某种类型的标头,但 re-graph 无法使用该选项。

4

2 回答 2

1

我遇到了同样的问题,我想我找到了解决方案。如@aarkerio 所述,重新帧请求遵循 Apollo规范。这是使原始端点与原始规范一起工作的代码,并允许它响应重新帧请求。这将使端点响应 Graphiql 请求(来自您的http://localhost:3000/graphiql路由),并重新绘制图形。欢迎任何意见或更正。

/graphql替换在路线上设置的原始功能src/clj/mem_learning/routes/services.clj

["/graphql" {:post graphql-call}

graphql-call在同一个文件上添加函数:

(defn graphql-call [req]
  (let [body (:body-params req)
        content-type (keyword (get-in req [:headers "content-type"]))]
    (case content-type
          :application/json (ok (graphql/execute-request-re-graph body))
          :application/graphql (ok (graphql/execute-request (-> req :body slurp))))))

添加execute-request-re-graphsrc/clj/mem_learning/routes/services/graphql.clj文件中:

(defn execute-request-re-graph
  "execute request with re-graph/apollo format"
  [{:keys [variables query context]}]
  (lacinia/execute compiled-schema query variables context)))
于 2020-03-01T01:17:46.027 回答
0

回答:

看起来 Luminus 创建了一个中间件配置:

(defn service-routes []
  ["/api"
   {:coercion spec-coercion/coercion
    :muuntaja formats/instance
    :swagger {:id ::api}
    :middleware [;; query-params & form-params
             parameters/parameters-middleware
             ;; content-negotiation
             muuntaja/format-negotiate-middleware
             ;; encoding response body
             muuntaja/format-response-middleware
             ;; exception handling
             exception/exception-middleware
             ;; decoding request body
             muuntaja/format-request-middleware
             ;; coercing response bodys
             coercion/coerce-response-middleware
             ;; coercing request parameters
             coercion/coerce-request-middleware
             ;; multipart
             multipart/multipart-middleware
             ]}

评论“muuntaja/format-negotiate-middleware”行使“application/json”调用成为可能。

第二次更新(四小时后)

好的,那个 muuntaja 中间件根本不是问题,真正的问题是 curl 以以下格式发送数据:

{ test_by_id(id: 7, archived: false) { title } }

同时 re-graph 使用:

{"query":"query { test_by_id(id: 7, archived: false) { title } }","variables":null}

这是一个普通的java字符串btw不是数据结构,所以我们需要做一些改变,首先是一个新函数:

(defn graphql-call [req]
  (let [body       (-> req :body slurp)
    full-query (json/read-str body :key-fn keyword)
    _          (log/info (str ">>>  **** full-query >>>>> " full-query))]
(ok (graphql/execute-request full-query))))

我们设置函数:

["/graphql" {:post graphql-call}]

my_app.routes.services.graphql文件中:

(defn execute-request [{:keys [variables query context]}]
  (json/write-str (lacinia/execute compiled-schema query variables context)))

现在重新绘制作品!

(现在我也可以在 GraphQL 中发送和使用变量了)

需要设置:

 :http-parameters         {:with-credentials? false
                           :oauth-token "ah4rdSecr3t"
                           :headers {"Content-Type" "application/graphql"}

顺便提一句。另外,也许它更好:

(lacinia/execute compiled-schema query variables context)

比:

(json/write-str (lacinia/execute compiled-schema query variables context)) 

因为它会干扰重新绘制已作为原生 ClojureScript 映射导入数据的图形。

于 2020-02-03T17:55:57.030 回答