GraphQL Is a Trap?

This page summarizes the projects mentioned and recommended in the original post on news.ycombinator.com

Our great sponsors
  • SurveyJS - Open-Source JSON Form Builder to Create Dynamic Forms Right in Your App
  • InfluxDB - Power Real-Time Data Analytics at Scale
  • WorkOS - The modern identity platform for B2B SaaS
  • trustfall

    A query engine for any combination of data sources. Query your files and APIs as if they were databases!

  • If you want to see what a GraphQL with an algebra could look like, I built one! The query language is parsed with a vanilla GraphQL parser, but has directives like `@filter, @recurse, @optional` etc.

    10min talk video: https://www.hytradboi.com/2022/how-to-query-almost-everythin...

    GitHub: https://github.com/obi1kenobi/trustfall

  • react-relay

    Relay is a JavaScript framework for building data-driven React applications.

  • > Checkout Relay.js: https://relay.dev/

    Relay is a GraphQL client. That's the irrelevant side of caching, because that can be trivially implemented by an intern, specially given GraphQL's official copout of caching based on primary keys [1], and doesn't have any meaningful impact on the client's resources.

    The relevant side of caching is server-side caching: the bits of your system that allow it to fulfill results while skipping the expensive bits, like having to hit the database.

    [1] https://graphql.org/learn/caching/

  • SurveyJS

    Open-Source JSON Form Builder to Create Dynamic Forms Right in Your App. With SurveyJS form UI libraries, you can build and style forms in a fully-integrated drag & drop form builder, render them in your JS app, and store form submission data in any backend, inc. PHP, ASP.NET Core, and Node.js.

    SurveyJS logo
  • ent

    An entity framework for Go

  • I feel like the original Twitter thread misses some common points. Bad API design is possible with any API style. A complex aggregation with nested joins is possible with any kind of API as transport. Also they don't mention tools like Relay, which indicates that they have never used GraphQL to its full extend. We've been working a lot in this space to improve the developer experience of GraphQL, giving devs the benefits of dynamic GraphQL operations but combining it with a REST API/JSON RPC as a facade and therefore dealing with a lot of the downsides. Please check our https://wundergraph.com/ if you're interested. In terms of security, there's frameworks like entgo (https://entgo.io) that handle auth extremely well. If you look closely into the docs, you'll realize that entgo supports REST, gRPC and GraphQL as external interface. So it's clear to say that you have to deal with authz, no matter what API style. Regarding "unpredictable" performance, I'm not sure I agree with the points being made. With GraphQL, it obviously gets very visible when you have "slow queries". If an API consumer would do the same "queries" through a REST API, it might be the case that they create even more server load because it takes more requests. The difference would be that it's not really visible because you don't count 100 rest API calls as "one query". Instead, you falsely believe that you've served 100 API calls very quickly in less than 100ms each. It might be the case that the REST API calls take 10s total, while the GraphQL query took 3s. So now you're thinking that REST is 30x faster than GraphQL, but really we're comparing apples to oranges. My summary is that you should choose the right frameworks and tools for your project. REST is totally fine, but please create an Openapi specification to document it, otherwise it gets messy.

  • join-monster

    A GraphQL to SQL query execution layer for query planning and batch data fetching.

  • genql

    Type safe TypeScript client for any GraphQL API

  • GraphQL is really useful paired with a tool like Genql [0] that creates a js library with auto completion and type safety, this makes discovering and using the API much easier and faster

    [0] https://github.com/remorses/genql

  • joystick

    A full-stack JavaScript framework for building stable, easy-to-maintain apps and websites.

  • Yes. It overcomplicates what can be a simple process using a bit of ingenuity and good ol' fashioned REST endpoints: https://github.com/cheatcode/joystick#customizing-outputs

  • restQL-core

    Discontinued Microservice query language

  • /network/shortestPath?node1=<>&node2=<>

    to get a list of all devices but I'm basically just writing custom Cipher code to do that query and the benefits of Neo4J basically go out the door. It still has some interesting Graph features but if all i'm doing is writing a custom endpoint for every use case it's mainly pointless.

    You can do a simple POST statement which takes a Neo4J query and execute it with some caching on top of it for sure.

    Either ways in order to make Neo4J worth it I need a way to make the queries more dynamic. So right now I'm thinking of:

    - restQL http://restql.b2w.io/

  • InfluxDB

    Power Real-Time Data Analytics at Scale. Get real-time insights from all types of time series data with InfluxDB. Ingest, query, and analyze billions of data points in real-time with unbounded cardinality.

    InfluxDB logo
  • foundation

    GraphQL Foundation Charter and Legal Documents (by graphql)

  • - GraphQL https://graphql.org/

    Or just having a dumb POST /custom/query that maybe only supports read operations. You can add a layer of auth but I'm not a big fan of just having some endpoint that's basically a Pipe to Neo4j. It feels just as bad as saying, typing any SQL here and we'll execute it on the server. If people know what they're doing that's fine..but at that point just setup phpMyAdmin/ pgAdmin. At that point you're trusting folks to know what they're doing and if folks accidently drop Bobby Tables (https://xkcd.com/327/) then it's an accepted risk.

    If you just have a proxy to run any Cipher query, you might as well just provide users on Neo4J web instance and let them play there.

    Anyways, still in early stages trying to figure out how to best leverage Neo4J

  • Hasura

    Blazing fast, instant realtime GraphQL APIs on your DB with fine grained access control, also trigger webhooks on database events.

  • edgedb

    A graph-relational database with declarative schema, built-in migration system, and a next-generation query language

  • You have to do your own optimiser to avoid, for instance, the N+1 query problem. (Just Google that, plenty of explanations around.) Many GraphQL frameworks have a “naive” subquery implementation that performs N individual subqueries. You either have to override this for each parent/child pairing, or bolt something on the back to delay all the “SELECT * FROM tbl_subquery WHERE id = ?” operations and convert them into one “… WHERE id IN (…)”. Sounds like a great use of your time.

    In the end you might think to yourself “why am I doing this, when my SQL database already has query optimisation?”. And it’s a fair question, you are onto it. Try one of those auto-GraphQL things instead. EdgeDB (https://edgedb.com) does it as we speak, runs atop Postgres. Save yourself the enormous effort if you’re only building a GraphQL API for a single RBDMS, and not as a façade for a cluster of microservices and databases and external requests.

    Or just nod to your boss and go back to what being a backend developer has always meant: laboriously building by hand completely ad hoc JSON versions of SQL RBDMS schemas, each terribly unhappy in its own way. In no way does doing it manually but presenting GraphQL deviate from this Sisyphean tradition.

    I read in the article that NOT having GraphQL exactly match your DB schema is a best practice. My response is “did a backend developer write this?”

  • query-counter

    SQLAlchemy model N+1 debugger!

  • I just got done doing a talk on GraphQL for PyCon2022 and I do agree with some of the points here. Performance work can be tedious and is not bi-directional in the graph so the number of dataloaders can blow up making debugging hard. Identifying where n+1 queries are in the API can also be difficult, but I used this open source package to help: https://github.com/tatari-tv/query-counter. I think the article failed to mention two of the things that GraphQL does really well: dense queries and built-in pagination. You're able to do the work of many serialized REST queries in one query using the node context of the GraphQL graph structure, which is a huge win if you're hitting performance issues related to requests per second to your API. Also pagination using the cursor, before/after, etc. is very helpful and Flask_Graphene enables some slick caching there to make subsequent queries at that cursor to be extremely performant. I have code with my sample implementation which simple, but shows the power of DataLoaders: https://github.com/lame/pycon-graphql.

  • pycon-graphql

  • I just got done doing a talk on GraphQL for PyCon2022 and I do agree with some of the points here. Performance work can be tedious and is not bi-directional in the graph so the number of dataloaders can blow up making debugging hard. Identifying where n+1 queries are in the API can also be difficult, but I used this open source package to help: https://github.com/tatari-tv/query-counter. I think the article failed to mention two of the things that GraphQL does really well: dense queries and built-in pagination. You're able to do the work of many serialized REST queries in one query using the node context of the GraphQL graph structure, which is a huge win if you're hitting performance issues related to requests per second to your API. Also pagination using the cursor, before/after, etc. is very helpful and Flask_Graphene enables some slick caching there to make subsequent queries at that cursor to be extremely performant. I have code with my sample implementation which simple, but shows the power of DataLoaders: https://github.com/lame/pycon-graphql.

  • objection-filter

    Filter objection.js models over HTTP using complex search queries

  • https://github.com/tandg-digital/objection-filter

    Out of curiosity, would functionality like this implemented in graphql solve your issues?

  • graphql-cached-get

  • Here's the code: https://github.com/RedShift1/graphql-cached-get

    Note that I made a very primitive implementation. Depending on which GraphQL node is queried, the request will be cached by the proxy or not. Apollo GraphQL server has much more fine grained methods of allowing caching (see https://www.apollographql.com/docs/apollo-server/performance...) however I left the example code crude so you see exactly what's going on under the hood.

  • postgrest

    REST API for any Postgres database

  • WorkOS

    The modern identity platform for B2B SaaS. The APIs are flexible and easy-to-use, supporting authentication, user identity, and complex enterprise features like SSO and SCIM provisioning.

    WorkOS logo
NOTE: The number of mentions on this list indicates mentions on common posts plus user suggested alternatives. Hence, a higher number means a more popular project.

Suggest a related project

Related posts