我使用的是最后一个可用的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 init向量,如下所示:
[::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 {}}]但是将头文件放入会使re无法正常工作:
{"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不能使用该选项。
发布于 2020-03-01 09:17:46
我也遇到了同样的问题,我想我已经找到了解决方案。重帧请求遵循阿波罗Specification,如@aarkerio所述。下面是保持原始端点与origina规范一起工作的代码,并允许它响应重新帧请求。这将使端点响应Graphiql请求(来自您的http://localhost:3000/graphiql路由),并重新绘制图形。欢迎任何意见或更正。
在src/clj/mem_learning/routes/services.clj上替换/graphql路由上设置的原始函数
["/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))))))在src/clj/mem_learning/routes/services/graphql.clj文件中添加execute-request-re-graph:
(defn execute-request-re-graph
"execute request with re-graph/apollo format"
[{:keys [variables query context]}]
(lacinia/execute compiled-schema query variables context)))发布于 2020-02-04 01:55:57
答案:
看起来,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”行使得"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映射导入的重新绘制图形。
https://stackoverflow.com/questions/60022510
复制相似问题