-
-
Save miguelbermudez/10a4f2bcb2d6fe457a6d4a87e9384176 to your computer and use it in GitHub Desktop.
Lacinia Async Example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; file edited for brevity | |
(ns ex.graphql.schema | |
(:require [com.walmartlabs.lacinia.schema :as schema] | |
[com.walmartlabs.lacinia.parser.schema :as parser] | |
[com.walmartlabs.lacinia.util :as util] | |
[com.walmartlabs.lacinia.resolve :as resolve] | |
[com.stuartsierra.component :as component] | |
[clojure.java.io :as io] | |
[clojure.edn :as edn] | |
[clojure.tools.logging :as log] | |
[clj-http.client :refer [post]] | |
[cheshire.core :refer [generate-string]])) | |
;; Load schemas from EDN | |
(defn ^:private load-edn [filename] | |
(-> (io/resource filename) | |
slurp | |
edn/read-string)) | |
;;----------------------------------------------------------------------------- | |
;; Resolvers | |
;;----------------------------------------------------------------------------- | |
(defn ^:private prop-resolver | |
[prop-value] | |
(fn [context args value] | |
(get value prop-value))) | |
(defn ^:private do-req | |
[config options] | |
(let [{:keys [api-url]} (:data config) | |
{:keys [path body selector auth-header]} options | |
url (str api-url path) | |
headers (if auth-header | |
{"Authorization" auth-header} | |
{}) | |
body-json-str (generate-string body) | |
selector-fn (or selector #(-> % :body))] | |
(-> (post url (ddp-req-options {:body body-json-str | |
:headers headers})) | |
selector-fn))) | |
(defn lookup-patient | |
[config] | |
(fn [context args value] | |
(let [{:keys [id]} args | |
promise (resolve/resolve-promise)] | |
(.start (Thread. | |
#(try (resolve/deliver! promise (-> (do-req config {:path "some/path" | |
:body {:id id} | |
:auth-header (get-in context [:request :headers "authorization"] nil) | |
:selector (fn [resp-body] | |
(-> resp-body :body (get "data") first))}) | |
(resolve/with-context {:id id}))) | |
(catch Throwable t (resolve/deliver! promise nil | |
{:message (str "Exception: " (.getMessage t))}))))) | |
promise))) | |
(defn surgery-for-patient [config] | |
(fn [context _ parent] | |
(let [{:keys [:id]} context | |
promise (resolve/resolve-promise)] | |
(println parent) | |
(.start (Thread. | |
#(try (resolve/deliver! promise (do-req config {:path "some/path" | |
:body {:somekey foo} | |
:auth-header (get-in context [:request :headers "authorization"] nil) | |
:selector (fn [resp-body] | |
(-> resp-body :body (get "data")))})) | |
(catch Throwable t | |
(resolve/deliver! promise nil | |
{:message (str "Exception: " (.getMessage t))}))))) | |
promise))) | |
(defn pathology-for-patient [config] | |
(fn [context _ _] | |
(let [{:keys [id]} context | |
promise (resolve/resolve-promise)] | |
(.start (Thread. | |
#(try (resolve/deliver! promise (do-req config {:path "some/path" | |
:body {:somekey foo} | |
:auth-header (get-in context [:request :headers "authorization"] nil) | |
:selector (fn [resp-body] | |
(-> resp-body :body (get "data")))})) | |
(catch Throwable t | |
(resolve/deliver! promise nil | |
{:message (str "Exception: " (.getMessage t))}))))))) | |
promise) | |
(defn resolver-map | |
"Graphql Resolvers" | |
[component] | |
(let [config (:config component)] | |
{ :prop prop-resolver | |
:patient/surgery (surgery-for-patient config) | |
:patient/pathology (pathology-for-patient config) | |
:query/patient (lookup-patient config)})) | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{:objects | |
{:Surgery | |
{:description "Surgery Item" | |
:fields {:procedureDate {:type (non-null String) | |
:description "Procedure Date" | |
:resolve [:prop "Procedure Date"]}}}} | |
:Patient | |
{:description "A MSK Patient." | |
:fields {:bmi {:type (non-null String) | |
:description "Body Mass Index" | |
:resolve [:prop "BMI"]} | |
:surgery {:type (list :Surgery) | |
:description "Surgeries performed on patient." | |
:resolve :patient/surgery} | |
:pathology {:type (list :Pathology) | |
:description "Patient's Pathology events." | |
:resolve :patient/pathology}}}} | |
:queries | |
{:patient | |
{:type :Patient | |
:description "Lookup patient by id." | |
:args {:id {:type (non-null ID)}} | |
:resolve :query/patient}}} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment