Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is it possible to define a custom scalar ? #51

Open
mariogarcia opened this issue Jan 4, 2017 · 2 comments
Open

Is it possible to define a custom scalar ? #51

mariogarcia opened this issue Jan 4, 2017 · 2 comments

Comments

@mariogarcia
Copy link

Hi:

First of all, great work \o/

My question is about scalar types. Sometimes is annoying to be dealing with data conversion in my application logic and I'm wondering if it's possible to register a new scalar converter somehow.

Thanks

@tendant
Copy link
Owner

tendant commented Jan 4, 2017

I am also considering to add Coercion support for all types, including Scalar, Object types and possibly Input Object.

We might be able to use the same way we define the resolver. Or enhance the resolver function with data coercion support.

@mariogarcia
Copy link
Author

Well after taking a look to the graphql-java project and this one I think the strategy I'd like the most is to keep things separated:

  • Schema definition file
  • Type/Field function resolvers (maybe in a DSL)
  • Scalar converters

All of them could be combined at the beginning to get the executor context (resolver), something like:

Type/Field function resolver DSL:

(def routes
  "GraphQL routing definition"
  [[:QueryRoot
    [auth/check-logged-in] ;; all queries under QueryRoot require to be logged in
    [:user users/find-by-email]
    [:course courses/by-id]
   ;; Relationships
   [:Course
    [:members courses/members]]])

One of the ideas of having a DSL is to be able to build a pipeline. That would help you applying things like authorization, or monitoring certain types...etc. (I'm actually implementing a basic version of the one above). Of course a pipeline requires that functions in the pipeline should return a type (not a graphql type I'm talking about defrecord deftype...) to let the pipeline know

  • when there's an error
  • when there's a delegation function
  • when to finish the pipeline with the final result.

Then Scalar converters. Coertion is ok, but I rather have the chance to be explicit in the conversion (from/to string). Anyway I'd like to know what you had in mind about coercion, maybe I got it wrong.

(def scalars
  "GraphQL scalars conversions"
  [[:UUID
    [converter/to-uuid converter/from-uuid]]
   [:Timestamp
    [converter/to-timestamp converter/from-timestamp]]])

Finally you can end up with something like this:

(def mappings (graphql/create-mappings routes))
(def schema (graphql/load-schema "graphql/schema.gql"))
(def resolve (graphql/create-resolver schema mappings scalars))

And use the resolve function in any known web framework or toolkit.

(defn execute-graphql
  "GraphQL endpoint"
  [ctx]
  (let [mp (:data ctx)
        qy (get-in mp ["query"])
        vs (get-in mp ["variables"])
        rs (graphql/resolve nil qy vs)]
    (-> (json/encode rs)
        (http/ok {:content-type http-util/json-type}))))

Sorry if my answer was too long.
Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants