Git Product home page Git Product logo

pathom3-graphql's Introduction

Pathom 3 GraphQL Clojars Project Test

This library provides an implementation to integrate GraphQL services in Pathom environments.

Example setup

(ns com.wsscode.pathom3.graphql.test.swapi
  (:require
    [clojure.data.json :as json]
    [com.wsscode.misc.coll :as coll]
    [com.wsscode.pathom3.connect.built-in.resolvers :as pbir]
    [com.wsscode.pathom3.connect.indexes :as pci]
    [com.wsscode.pathom3.graphql :as p.gql]
    [com.wsscode.pathom3.interface.eql :as p.eql]
    [org.httpkit.client :as http]))

(defn request [_ query]
  (-> @(http/request
         {:url     "https://swapi-graphql.netlify.app/.netlify/functions/index"
          :method  :post
          :headers {"Content-Type" "application/json"
                    "Accept"       "*/*"}
          :body    (json/write-str {:query query})})
      :body
      json/read-str))

(def env
  (-> {}
      (p.gql/connect-graphql
        {::p.gql/namespace "swapi"}
        request)))

(p.eql/process
  env
  [{:swapi.Root/allFilms
    [{:swapi.FilmsConnection/films
      [:swapi.Film/director
       :swapi.Film/title]}]}])

(p.eql/process
  env
  {:swapi.Film/id "ZmlsbXM6Mg=="}
  [:swapi.Film/title])

Check the demos folder for more example setups.

pathom3-graphql's People

Contributors

wilkerlucio avatar cjsauer avatar tylernisonoff avatar

Stargazers

 avatar Ren Strydom avatar Simon Accascina avatar Kenji Nakamura avatar Alex Sheluchin avatar Raph avatar Enzzo avatar Ian Fernandez avatar Paulo Rafael Feodrippe avatar Adam Feldman avatar Jeroen van Dijk avatar Aram Zadikian avatar Joël Kuiper avatar 胡雨軒 Петр avatar Vincent Cantin avatar Leandro Pincini avatar Matheus Francisco avatar

Watchers

 avatar James Cloos avatar

pathom3-graphql's Issues

Nested resolver inputs misbehave beyond a certain level

I'm running into something a little weird with GitHub GraphQL.

This query works fine:

(p/let [result (p.eql/process github-gql-env
                {:github.Organization/login "fulcrologic"}
                ['({:github.Organization/repositories
                    [{:github.RepositoryConnection/edges
                      [{:github.RepositoryEdge/node
                        [:github.Repository/name
                         :github.Repository/nameWithOwner
                         {:github.Repository/owner [:github.RepositoryOwner/id]}]}]}]}
                   {:first 1})])]
  (doto result tap>))

Returning:

#:github.Organization
{:repositories
 #:github.RepositoryConnection
 {:edges
  [#:github.RepositoryEdge
   {:node
    #:github.Repository
    {:name "fulcro",
     :nameWithOwner "fulcrologic/fulcro",
     :owner #:github.RepositoryOwner
            {:id
             "MDEyOk9yZ2FuaXphdGlvbjMwMTAyODIz"}}}]}}

But when I try this nearly identical query through a resolver, I get an error:

(pco/defresolver shortcut
 [{{edges :github.RepositoryConnection/edges} :github.Organization/repositories
   :as input}]
 {::pco/input [{'(:github.Organization/repositories {:first 1})
                [{:github.RepositoryConnection/edges
                  [{:github.RepositoryEdge/node
                    [:github.Repository/id
                     :github.Repository/name
                     :github.Repository/nameWithOwner
                     {:github.Repository/owner [:github.RepositoryOwner/id]}]}]}]}]
  ::pco/output [{:github.Organization/all-repos
                 [:github.Repository/id
                  :github.Repository/name]}]}
 {:github.Organization/all-repos (mapv :github.RepositoryEdge/node edges)})

"Pathom can't find a path for the following elements in the query: [:github.RepositoryOwner/id] at path [:github.Organization/repositories]"

If I remove {:github.Repository/owner [:github.RepositoryOwner/id]} from the resolver input, it works. It seems like joins on other fields in the same location don't work either. For example, {:github.Repository/issues [:github.IssueConnection/totalCount]}.

Any idea what I'm doing wrong here?

Index schema to Pathom 3 indexes

This task will use the new idea of auxiliary dynamic resolvers from Pathom 3 to encode the schema.

In the previous version, we had to manually write each index, which makes it a challenge to ensure they are consistent. The new method uses extra resolvers instead, which makes indexing more consistent and easier to implement.

Support for GraphQL field aliases

Pathom doesn't currently support GraphQL field aliases. Adding support for them would enable batching some queries into a single request, like this:

{
  x: search(query: "torvalds", type: USER, first: 1) {
    edges {
      node {
        ... on User {
          createdAt
        }
      }
    }
  }
  y: search(query: "richhickey", type: USER, first: 1) {
    edges {
      node {
        ... on User {
          createdAt
        }
      }
    }
  }
}

Otherwise, omitting the aliases (x: and y:), GitHub returns an error:

{
  "errors": [
    {
      "path": [],
      "extensions": {
        "code": "fieldConflict",
        "fieldName": "search",
        "conflicts": "{query:\"\\\"torvalds\\\"\",type:\"USER\",first:\"1\"} or {query:\"\\\"richhickey\\\"\",type:\"USER\",first:\"1\"}"
      },
      "locations": [
        {
          "line": 7,
          "column": 3
        },
        {
          "line": 16,
          "column": 3
        }
      ],
      "message": "Field 'search' has an argument conflict: {query:\"\\\"torvalds\\\"\",type:\"USER\",first:\"1\"} or {query:\"\\\"richhickey\\\"\",type:\"USER\",first:\"1\"}?"
    }
  ]
}

I'm just creating this issue to document that there is no current support for this and to explain how it could be useful.

Simplify GraphQL query generation

Pathom 3 GraphQL makes extensive use of the GraphQL ... of Type feature, to allow any possible attribute (considering interfaces) to be fetched at a given point.

A user found on Slack that the Github API seems to have a problem with some of those cases, an example repro:

[{:github.Query/viewer
  [{(:github.User/repositories {:first 1})
    [{:github.RepositoryConnection/edges
      [{:github.RepositoryEdge/node
        [:github.Repository/name
         {:github.Repository/issues
          [:github.IssueConnection/totalCount]}]}]}]}]}]

This currently generates the following GraphQL query:

query {
  __typename
  ... on Query {
    viewer {
      __typename
      ... on User {
        repositories(first: 1) {
          __typename
          ... on RepositoryConnection {
            edges {
              __typename
              ... on RepositoryEdge {
                node {
                  __typename
                  ... on Repository {
                    name
                    issues {
                      __typename
                      ... on IssueConnection {
                        totalCount
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

Fix idea: make the GraphQL generation smarter and avoid using ... of Type when requesting attributes directly from a type (instead of an interface).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.