GraphQL Interface #18
Replies: 6 comments 3 replies
-
I've started to look at this and wanted to share some thoughts. In general i agree we should follow a similar idea that Graffiti used. We should continue to use specs to generate a Lacinia schema.
Ex: (s/def ::id int?)
(s/def ::operational boolean?)
(s/def ::droid (s/keys :req [::id ::name]
:opt [::operational]))
(s/def ::droid-query (s/keys :req [::id]
:opt [::operational]))
(pco/defresolver droid-resolver [env {::keys[id]}]
(when (get (pco/params env) ::operational)
{::name "a name" ::operational? true}))
{:lacinia/query
{::droid-query ::droid}} With some help from the pathom index we could identify from the { droid (id: 1, operational: true) { name }} ;; graphql query [({::droid 1} [name] {::operational true})] ;;inferred eql query Not sure how complicated this could become with more complex queries. In the worst case we could follow a similar idea as graffiti were the programmer had to manually specify input and args. ex: {:lacinia/query
{::droid-query {:type ::droid
:input [::id]
:params [::operational]}}}
|
Beta Was this translation helpful? Give feedback.
-
Following the idea above to use spec-tools to add metadata to specs, we could create a lacinia schema similar to this one using something like: (s/def ::episode #{:newhope :empire :jedi})
(s/def ::id string?)
(s/def ::appears-in (s/coll-of ::episode))
(s/def ::friends (s/coll-of ::character))
(s/def ::primary-function (s/coll-of string?))
(s/def ::home-planet string?)
(s/def ::character (s/keys :req-un [::id ::name ::appears-in ::episode]))
(s/def ::droid (s/merge ::character (s/keys :req-un [::primary-function] )))
(s/def ::human (s/merge ::character (s/keys :req-un [::home-planet] )))
(s/def ::hero-args (s/keys :req-un [::episode]))
(s/def ::human-args (s/keys :req-un [::id]))
(s/def ::droid-args (s/keys :req-un [::id]))
(def episode (st/spec ::episode {:graphql/description "The episodes of the original Star Wars trilogy."}))
(def character (st/spec ::character))
(def droid (st/spec ::droid {:graphql/implements ::character}))
(def human (st/spec ::human {:graphql/implements ::character}))
(def hero-query (st/spec ::hero-args {:graphql/type ::character}))
(def human-query (st/spec ::human-args {:graphql/type (s/nilable human)}))
(def droid-query (st/spec ::droid-args {:graphql/type (s/nilable droid)}))
;; lacinia/schema is a function that uses spec-tools visitors to generate the lacinia schema
(def schema (lacinia/schema #:graphql{:enums [episode]
:interfaces [character]
:objects [droid human]
:queries [hero-query human-query droid-query]}))
|
Beta Was this translation helpful? Give feedback.
-
I'm working on this (a Lacinia schema powered by Pathom) and want to share my vision too: I agree with you guys about the GraphQL object parts, the dynamic nature of Pathom can't (shouldn't?) address this. So I'll consider GraphQL schema objects and GraphQL queries as separate problems. I didn't even consider mutations and subscriptions yet. GraphQL objectsWe are heavy Prismatic schema users at BeOp so I've worked on a simple GraphQL queriesI've chosen to declare the queries explicitly, it helps controlling and documenting what part of the Pathom graph becomes a valid entry point for consumers. I'm thinking now about what's the best way to declare and feed "joins" in the schema from Pathom, (in GraphQL can be seen as the relations between objects, for instance a list of addresses for a given user). I also plan to make this explicit, probably by adding fields in the GraphQL objects with the same name as the Pathom resolvers output, to leverage the root query resolver also (I want to keep Pathom as the fetching orchestrator). Not sure it's very clear 😅 I'll try to share some code soon. |
Beta Was this translation helpful? Give feedback.
-
I started doing a direct translate from the GraphQL AST (Lacinia provides it) to EQL Queries. this appeared a promising idea. It would allow you to given a request with a GraphQL query, it turns into a EQL Query, runs on pathom and return the value. But deliver a GraphQL API without a schema will make most of the GraphQL users freakout. I thought in some ideas like
|
Beta Was this translation helpful? Give feedback.
-
Update: (sorry it might be a bit off-topic, let me know) So instead, I've thought about a small DSL, which is a bit more verbose but translates easily to EQL (or AST of course), and is more JSON-compliant (map keys are always strings, never composite). Ex: on the front side (2) ["account/name",
{"key": "account/default_settings.location_expanded",
"pathom/as": "account/default_settings.location",
"query": ["location/name", "'*"]}] is mapped back-side into [:account/name
{'(:account/default_settings.location_expanded {:pathom/as :account/default_settings.location})
[:location/name '*]] And would result in (3) {"name": "my account",
"default_settings": {"location": {"name": "..."}}} Notes: |
Beta Was this translation helpful? Give feedback.
-
Most of the ideas we have discussed here are now available Graffito Hopefully an initial announcement could bring more interested people to work on the ideas discussed here. Cheers |
Beta Was this translation helpful? Give feedback.
-
For a long time, there is been conversations here and there about some way to provide a GraphQL API interface, leveraged by Pathom.
I'm creating this page to concentrate on the current ideas so people willing to work on them can find them in a single place.
A big challenge for this feature is to decide what the GraphQL API looks like, given the dynamic nature of Pathom, many different API shapes could be considered valid. To constrain that to a sane GraphQL API, I believe there is a need for some manual intervention, some configuration to decide how to shape out the GraphQL from a Pathom one.
Compatible with Pathom 2, there is the library Graffiti that uses Lacinia to make a bridge between Pathom and GraphQL. I think this is a good interface, and Lacinia is a good idea, so they do a lot of GraphQL hard parts.
This is what I have now, everybody is welcome to join the discussion here.
Beta Was this translation helpful? Give feedback.
All reactions