Lacinia и перепрограммировать несовместимые заголовки - PullRequest
1 голос
/ 02 февраля 2020

Я использую последнюю доступную версию lacinia: «0.36.0-alpha-3» с Luminus (Ring + reitit), но эта версия запрашивает определенный c заголовок:

$ 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', 

это выглядит как ре-граф отправляет и получает данные, используя заголовок «application / json», поэтому lacinia запрашивает какой-либо тип заголовка, но повторный график не может работать с этой опцией.

Ответы [ 2 ]

1 голос
/ 01 марта 2020

У меня была такая же проблема, и я думаю, что нашел решение для нее. запросы на повторный кадр следуют спецификации Apollo , заявленной @aarkerio. Вот код, который позволяет исходной конечной точке работать со спецификацией originina и разрешать ей отвечать на запросы перекадровывания. Это заставит конечную точку отвечать на запрос 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-graph в файл src/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)))
0 голосов
/ 03 февраля 2020

ОТВЕТ:

Похоже, что 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 -gotiate-middleware" делает " application / json "вызов возможен.

ВТОРОЕ ОБНОВЛЕНИЕ (четыре часа спустя)

Хорошо, эта вещь промежуточного программного обеспечения muuntaja не была проблемой вообще, настоящей проблемой это то, что curl отправляет данные в формате:

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

, в то время как ре-граф использует:

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

это обычная java строка, кстати, не структура данных, поэтому мы нужно сделать некоторые изменения, сначала новую функцию:

(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.

...