[HN Gopher] GQless: A GraphQL client built for rapid iteration
       ___________________________________________________________________
        
       GQless: A GraphQL client built for rapid iteration
        
       Author : rgbrgb
       Score  : 94 points
       Date   : 2021-06-01 16:46 UTC (1 days ago)
        
 (HTM) web link (gqless.com)
 (TXT) w3m dump (gqless.com)
        
       | [deleted]
        
       | millerm wrote:
       | I'm very interested in this! Thanks for posting!
        
       | atom_arranger wrote:
       | This looks like it has a shot at being a better developer
       | experience than Relay while still encouraging the use of nested
       | queries (unlike clients like Apollo and urql). Nice.
        
         | zwily wrote:
         | How do Apollo and urql discourage using nested queries?
        
       | tompazourek wrote:
       | It reminds me a little bit of QBE (Query by example), but instead
       | of saying what data you want, you say what schema you want.
        
       | beaunative wrote:
       | This is amazing concept. It literally transforms remote api into
       | local resource with the aid of graphql.
        
       | k__ wrote:
       | I really like these event-loop/proxy-object tricks.
       | 
       | It always feels like magic.
        
       | bionhoward wrote:
       | ES6 Proxy is awesome
        
       | elitan wrote:
       | Wow, that's cool!
        
         | hrpnk wrote:
         | Cool for prototyping, but likely difficult to maintain over a
         | longer period of time.
         | 
         | Just like with an ORM on top of a DB, if one needs to to
         | performance optimization or support parallel app versions and
         | ensure backwards-compatibility of queries, the actual queries
         | are useful if not essential to know and manage.
        
           | nwienert wrote:
           | There's no reason all of this isn't supported as well if not
           | better in GQless than any other client.
           | 
           | You can hoist the query logic if you need to ensure it stays
           | static for some reason.
           | 
           | I've built a very large app with this and am perfectly happy
           | with the model, it has many upsides vs having to manually
           | link strings into views, like never overfetching and having
           | fully typed queries without any plugins.
        
       | coding123 wrote:
       | One of our requirements is to disable schema downloading in
       | production in apollo server. (We can have it enabled in
       | dev/local). Can this work if that is disabled? (Yes we know this
       | is silly but our auditor caught it)
        
         | harg wrote:
         | From my understanding this should work as the schema is
         | introspected ahead of time. This gives all the type information
         | needed for the `useQuery` hook to work properly. Just the
         | queries themselves are generated at runtime; there shouldn't be
         | any need to introspect the schema then.
         | 
         | Where this might have an issue is with persisted queries. But
         | then you'd need some sort of client/server build tooling to
         | keep them in sync.
        
         | wereHamster wrote:
         | What's the reasoning behind not allowing it?
        
           | nguyenkien wrote:
           | Hiding details
        
       | outerlook wrote:
       | the greatest value on it for me is the scalability of relay,
       | without the boilerplate.
       | 
       | Colocating data requirements next to where it is using it without
       | writing it two times is awesome!
        
       | felipellrocha wrote:
       | This is great except for one thing. I like types generates during
       | static time, not runtime. Anyway we could verify types at that
       | time?
        
         | nwienert wrote:
         | It generates types via CLI statically up front, all queries are
         | then fully typed, only the final request is generated at
         | runtime which means you never fetch anything except what you
         | need.
        
       | ericlewis wrote:
       | So instead of having a schema a schema is created from the React
       | usage? I am not entirely sure what this does.
        
         | linkdd wrote:
         | If I understand correctly, it's more like the query (not the
         | schema) is generated from the expected result.
         | 
         | So your application does not need to "talk in GraphQL".
        
           | millerm wrote:
           | The main advantage is that the query is resolved at runtime.
           | It only queries for exactly what your component needs. No
           | over-querying. No sharing queries across components, which is
           | a huge mistake people make.
        
             | golergka wrote:
             | > query is resolved at runtime
             | 
             | Does it mean that we get errors at runtime and not build
             | time, too?
        
               | SketchySeaBeast wrote:
               | Have you found a way to get build errors with GraphQL
               | queries? I only ever get them during runtime when the
               | request is made, I assume because that's the point at
               | which the back-end and front-end disagree on what you're
               | requesting.
        
               | nawgz wrote:
               | Using Typescript,GraphQL-codegen, and Hasura, I can build
               | correct-by-construction React apps. GraphQL-codegen &
               | Hasura introspect the DB to type the query result, and
               | typescript confirms my JS is not accessing any of those
               | fields illegally.
               | 
               | It's pretty killer to open GraphiQL, write a new query,
               | drop it into a graphql file in my repo, rerun the
               | codegen, and be able to have type safe operations on the
               | queried data.
               | 
               | Also makes me completely unsure why anyone would want
               | what the OP is but that's ok
        
               | atom_arranger wrote:
               | This solution seems to work like this:                 -
               | Generate type safe client based on your schema.       -
               | Access GraphQL properties as if they were just JS object
               | properties.
               | 
               | So in this solution the codegen step comes before writing
               | a query.
               | 
               | You get the same advantages pretty much, and you have
               | less likelihood of querying for unused data.
        
               | potatoz2 wrote:
               | If you generate types from your GraphQL queries, they are
               | validated against the schema at that time (so you'd get
               | schema errors then, of course there can still be network
               | errors, server errors or user/semantic errors at runtime)
        
               | revskill wrote:
               | This part is confusing to me.
               | 
               | I prefer this will validate our component for correct
               | schema usage at build time.
        
               | nwienert wrote:
               | It fully typed, so you get errors at build time.
        
               | coding123 wrote:
               | I think the part that's throwing people off (including
               | me) is if I'm looking at that main example, how do I get
               | type completion on this line:                   Hello
               | {query.me.name}!
               | 
               | query dot me dot name should all have type completion.
               | And in most TS "frameworks" you have some way to type
               | hint this all out. us TS folk are not seeing the type
               | hints in the example. Maybe it works in VSCode like that,
               | but totally confused how it does.
               | 
               | Believe me, I'm super interested in this project and it
               | would save a ton of time if it's doing what some of us
               | are hoping :)
        
               | nwienert wrote:
               | It does autocomplete with types on that line, and yes,
               | it's really that cool.
               | 
               | Disclosure: I funded the development of version 2, and
               | have written a large app using it. I am very happy with
               | it, and believe it's the best data fetching solution
               | around.
        
             | andrewingram wrote:
             | I'd say you're broadly right, the key idea is that your
             | client code has a facade over the fact that you're using
             | GraphQL, so it looks cleaner -- it's "just JavaScript".
             | Whether this is an advantage or not is largely down to
             | preference.
             | 
             | The "Why" section in the docs is a pretty good summary:
             | 
             | https://gqless.com/intro#why
             | 
             | "I wanted a GraphQL client that lets you forget you're
             | using GraphQL, whilst tackling some issues shared across
             | all existing GraphQL clients"
             | 
             | The fact that it's resolved at runtime isn't necessarily an
             | advantage, it locks you out of some performance and
             | security patterns. I believe GQLess is investigating
             | support for static extraction of queries at build time.
             | 
             | It's an interesting API, I'm not entirely sold on the idea
             | of disguising the fact that you're using GraphQL though.
        
       | a_humean wrote:
       | How do you deal with error handling? I don't see anything in the
       | docs about error handling.
       | 
       | How do you deal with union types? The docs seem completely scant
       | on that.
       | 
       | Otherwise very interesting approach.
        
         | merrywhether wrote:
         | The useQuery hook's opts have an onError property that accepts
         | a callback.
         | 
         | I also don't see anything about union types. That definitely
         | seems like the hardest thing to reverse construct based on
         | usage, since the underlying proxy wouldn't know what you're
         | doing with __typename.
        
         | occz wrote:
         | Handling loading states also seems to be a little bit on the
         | anemic side, but I didn't investigate too deeply.
        
           | a_humean wrote:
           | Yes, it doesn't really distinguish between loading vs null
           | values in any of the examples.
           | 
           | My guess is its going to be something like `undefined` means
           | loading and `null` means null.
        
             | nwienert wrote:
             | There's a different hook you can use that returns an error
             | state.
        
           | merrywhether wrote:
           | The primary example code relies on Suspense, meaning that
           | loading behavior will be handled by a parent/ancestor
           | <Suspense /> component and not in the component itself. I
           | think they default to showing this pattern since it is the
           | "future" of React. There is an alternate version of the API
           | where you can get a loading boolean for imperative control.
        
       ___________________________________________________________________
       (page generated 2021-06-02 23:01 UTC)