News for hackers. Stuff that matters.
Re:GraphQL Is a Trap? by masklinn on Friday May 06, 2022 @10:17AM (#31285396)
> GraphQL is a great experience when you consume it and the service fulfills your query needs. Because you just ask stuff and you get them. It's really cool.

I guess it's better when the tooling you use has direct gql integration and builds the queries for you?

Because in my experience accessing the github APIs with "basic" HTTP libraries is way more annoying using v4 (graphql) than v3 ("rest") — it could also be that github's v4 API is dreadful mind, I wouldn't be surprised.

GQL should be more efficient because it's not returning 95% of garbage I don't need, but having to write 5-deep queries (because of the edge indirections) by hand is way more of a pain in the ass than performing two GET requests with a few parameters munged in the URLs. And then I still have to go and retrieve the information 5-deep in the resulting document.

Pagination is also awkward, because now you probably want multiple different queries (and thus multiple different resulting documents) so that your 2+ fetches don't retrieve unpaginated information you got the first time around. And it gets worse when nesting comes in.

I don't think graphql is generally a great experience when you consume it either.

Re:GraphQL Is a Trap? by obi1kenobi on Friday May 06, 2022 @11:30AM (#31286333)
100% agree that pagination is extremely awkward, especially with nesting. Between the pagination problem and the "oops I asked for too much data and blew up the server" problem, I think it's more work than one might think to run a GraphQL API.

For my own work, I took things in a different direction: I made a query language that parses as legal GraphQL using a vanilla parser, but has directives like `@filter, @recurse, @optional` etc. Instead of returning a giant fully-nested result, it flattens results and emits them row-by-row like a SQL database. This means the query evaluation can be lazy and incremental — if you write a query that has a billion results but only load 20 of them, then only 20 rows' worth of work happens.

My company has been using this in production for 6 years now across everything from TB-scale SQL clusters with X00,000 tables/views, to querying our own codebase, configuration, and deployment information to find and prevent bugs. I gave a 10min talk at a conference about this recently, if you'd like to learn more: https://www.hytradboi.com/2022/how-to-query-almost-everythin...

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

Re:GraphQL Is a Trap? by pstuart on Friday May 06, 2022 @06:22PM (#31290178)
Starred and noted for a project I'm working on. Thanks!
Re:GraphQL Is a Trap? by Southland on Friday May 06, 2022 @05:44PM (#31289893)
This is super cool. Thanks for sharing
Re:GraphQL Is a Trap? by brasic on Friday May 06, 2022 @11:44AM (#31286514)
I work at GitHub and would love to hear more. Can you describe some of the data interactions that you find more convenient with the v3 API?
Re:GraphQL Is a Trap? by dmitshur on Friday May 06, 2022 @06:06PM (#31290053)
Not parent, but my biggest challenge is some v3 APIs are not there in v4 yet. For example, activity and notifications (https://docs.github.com/en/rest/activity/notifications) is something I'm still looking forward to, but forced to keep using REST until it becomes available via GraphQL.

The pagination point is described well in nearby comments. It only applies when attempting to paginate across more than 1 dimension at once, like "get all pages of comments in an issue, and all pages of reactions for each comment".

Re:GraphQL Is a Trap? by brasic on Friday May 06, 2022 @10:21PM (#31291635)
Thank you! I agree that there is more we could do to reach parity here.

Is paginating across multiple dimensions possible via the REST API?

Re:GraphQL Is a Trap? by sieabahlpark on Friday May 06, 2022 @04:38PM (#31289403)
Everything is easier to use with rest because it's so simple it works with curl trivially.
Re:GraphQL Is a Trap? by Beltalowda on Friday May 06, 2022 @05:16PM (#31289691)
Not just cURL; most of the time I want something from the GitHub API it's something fairly simple; using REST from Python, Go, Ruby, $preferred_language is easier than using GraphQL, too. I'm sure there are libraries out there, but hard to beat a simple "fetch me data from that URL yo".
Re:GraphQL Is a Trap? by brasic on Friday May 06, 2022 @10:20PM (#31291627)
GraphQL uses HTTP like the REST API and speaks JSON. There's no need for a library if you're comfortable sending a POST request.

It seems to me like the main friction that you and others are getting at is that GraphQL is more work to use than REST because you have to write a query. That's a fair point! Perhaps we could publish "canned" queries that are the equivalent of the most commonly used REST endpoints, or make them available for use in the API with a special param.

Re:GraphQL Is a Trap? by Beltalowda on Saturday May 07, 2022 @02:29PM (#31297171)
Yes, you need to write a query; and it's also not at all that obvious how to write a query. Let's say you want to list all repos belonging to a user or organisation, a fairly simple and common operation. I found [1] in about 30 seconds. I've been trying to do the same with GraphQL for five minutes now using the docs and GraphQL Explorer, and thus far haven't managed to get the same result.

I worked a bit with GraphQL in the past, but never all that much. Now, I'm sure I could figure it out of I sit down, read the basics of GraphQL, familiarize myself with GitHub's GraphQL schema, etc. But ... it's all a lot of effort and complex vs. the REST API; even with a solid foundation in GraphQL there's still lots more parts.

GraphQL is kind of like giving people a schema to an SQL database and telling them that's an "API"; it kind of is, but also isn't really. There's a reason almost all applications have some sort of database layer (API!) to interact with the database, rather than just writing queries on the fly whenever needed.

[1]: https://docs.github.com/en/rest/repos/repos

Re:GraphQL Is a Trap? by brasic on Saturday May 07, 2022 @04:09PM (#31298083)
That's completely fair. I think the analogy to SQL as an API is very apt. No one would argue that full SQL access isn't a powerful API but it takes some legwork to understand the schema and write queries to get the data you need.

There's a divide between at least two types of persona here. On one side is integrators building products and features on top of the GitHub API. For these people GraphQL is arguably superior since the learning curve is manageable and in exchange for scaling it you can make an extremely specific query that returns your product's exact data requirements. The cost of writing this query is amortized over the lifetime of your integration.

On the other side are e.g. users automating some part of their GitHub workflow to save themselves time. I can see how the REST API feels like a better choice here, it's certainly simpler to get started with.

For what it's worth, here[0] is an example of using the `gh` CLI's graphql feature to print a list of all repository URLs for a given organization by login, sorted in a relatively complicated way. It's more verbose than doing this with the REST API but significantly more flexible. This could just as easily be done with curl but as others have pointed out, pagination requires a minimal level of logic to implement, so it's more convenient to use an existing helper. This output gets flushed 10 lines at a time as pages come in, making it suitable to compose with other commands using pipes.

  $ gh api graphql --paginate -f query='
    query($endCursor: String) {
      organization(login: "rails") {
        repositories(first: 10, after: $endCursor,
                     orderBy: { field: STARGAZERS, direction: DESC }
        ) {
          nodes {
            url
            stargazers { 
              totalCount
            }
          }
          pageInfo { endCursor hasNextPage } # needed for auto-pagination
        }
      }
    }' -q '.data.organization.repositories.nodes.[]'
  # output follows
  {"stargazers":{"totalCount":50643},"url":"https://github.com/rails/rails"}
  {"stargazers":{"totalCount":5298},"url":"https://github.com/rails/webpacker"}
  {"stargazers":{"totalCount":4849},"url":"https://github.com/rails/thor"}
  {"stargazers":{"totalCount":4075},"url":"https://github.com/rails/jbuilder"}
  # snip
  {"stargazers":{"totalCount":3},"url":"https://github.com/rails/hide_action"}
  {"stargazers":{"totalCount":2},"url":"https://github.com/rails/gem-buildkite-config"}
  {"stargazers":{"totalCount":2},"url":"https://github.com/rails/sqlite2_adapter"}
  {"stargazers":{"totalCount":1},"url":"https://github.com/rails/fcgi_handler"}

[0]: https://gist.github.com/brasic/14222db7b3f5873b84820477cca27...
Re:GraphQL Is a Trap? by brasic on Friday May 06, 2022 @10:11PM (#31291586)
The GraphQL API works just as well with curl. There's no getting around the fact that you need to pass a query text but assuming you put the query in a file the curl syntax is identical to the REST API:

   curl https://api.github.com/graphql -H "Authorization: bearer $TOKEN" --data @query.graphql
Re:GraphQL Is a Trap? by Rapzid on Friday May 06, 2022 @04:58PM (#31289548)
> Everything is easier to use with rest because it's so simple it works with curl trivially.

Dead comment.

Re:GraphQL Is a Trap? by searchableguy on Friday May 06, 2022 @11:20AM (#31286204)
> Pagination is also awkward, because now you probably want multiple different queries (and thus multiple different resulting documents) so that your 2+ fetches don't retrieve unpaginated information you got the first time around. And it gets worse when nesting comes in.

You don't need to write a different graphql query, use variables. Good graphql APIs will expose a start and limit field for Pagination.

Re:GraphQL Is a Trap? by masklinn on Friday May 06, 2022 @11:31AM (#31286345)
I think you misunderstood the issue. Of course you will use variables for the pagination itself, the issue is that your head of line query will be grabbing other fields than the paginated one.

You don't want to repeat these fetches in the followup queries, they're redundant, and assuming the API is rate-limited they will decrease your query budget for no value.

That counts double if you're fetching multiple paginated fields (which also adds to the awkwardness).

Re:GraphQL Is a Trap? by obi1kenobi on Friday May 06, 2022 @11:37AM (#31286411)
Agreed — consider what happens when you have a node(start: Int, limit: Int) inside or alongside another such node with start and limit.

Your pagination is now two-dimensional, with each node's start/limit as points on its own axis.

Now add a third node to the query. Now you have three-dimensional pagination. This quickly goes off the rails.

Try writing a generic N-dimensional paginator for such a query to see why it's difficult. Even designing a sensible and reasonably flexible API for one is a headache.

Re:GraphQL Is a Trap? by searchableguy on Friday May 06, 2022 @11:44AM (#31286515)
I think I got what you are saying now. If you want to get paginated children nodes, then the root will be fetched again which is a problem.
Re:GraphQL Is a Trap? by masklinn on Friday May 06, 2022 @01:08PM (#31287519)
Indeed. It may not be a huge problem depending on how much data you need, but there are lots of cases where you'd really rather avoid refetching the rest of the root.

TBF you could also deal with it using fragments I think, but still, not great.

Re:GraphQL Is a Trap? by PaulHoule on Friday May 06, 2022 @11:42AM (#31286488)
Pagination is a bear.

Most of the simple ways of doing it with SQL are problematic. In these docs

https://docs.spring.io/spring-batch/docs/current/reference/h...

there is some discussion of the problems and some answers that go back to the mainframe era.

Re:GraphQL Is a Trap? by marcosdumay on Friday May 06, 2022 @02:38PM (#31288431)
The server side of pagination is really complex if you want to make sure all the results are returned exactly once. If that's your case, consider not paginating at all.

But very often, a result missing or duplicated in a few queries isn't a showstopper. On that case, pagination is very simple.

Re:GraphQL Is a Trap? by PaulHoule on Friday May 06, 2022 @03:53PM (#31289048)
Spring Batch covers the cases where you have to get the right answer!

That is you are "full scanning" and making a report or doing something like a reconciliation process in a financial institution, it is not like some image boards where there is a link to the 1781th page of images but it spends forever loading it if you click on it.

Re:GraphQL Is a Trap? by atom_arranger on Friday May 06, 2022 @02:29PM (#31288344)
> but having to write 5-deep queries (because of the edge indirections) by hand is way more of a pain in the ass than performing two GET requests with a few parameters munged in the URLs. And then I still have to go and retrieve the information 5-deep in the resulting document.

I usually write my queries in GraphiQL (check some boxes) and then paste them into the app after I have them working right.

Re:GraphQL Is a Trap? by dustymcp on Friday May 06, 2022 @01:36PM (#31287819)
Having consumed both and recently rewriting a lib to graphql i know enough to not wanting to roll my own..
Re:GraphQL Is a Trap? by camgunz on Friday May 06, 2022 @04:35PM (#31289379)
I think GraphQL is best understood as an incomplete ORM that you have to complete yourself on the backend. If GraphQL generated SQL (given some tooling or what have you) pretty much all the problems are solved. Indeed backend-as-a-service products like Hasura or Postgraphile are this missing piece. I guess we're uncomfortable with SQL over the wire or open-to-the-world databases, but we shouldn't be.

Or maybe TLDR "dear next generation of engineers: SQL is actually pretty good".

Re:GraphQL Is a Trap? by discreteevent on Friday May 06, 2022 @04:41PM (#31289427)
SQL is excellent but exposing your database is not. The inventors of graphql specifically said that they don't think that it is a good idea to do so. They never intended it for that.
Re:GraphQL Is a Trap? by camgunz on Saturday May 07, 2022 @01:56PM (#31296886)
> SQL is excellent but exposing your database is not.

That was definitely true before Postgres got row security (admittedly in 2016, after GraphQL was released in 2015), but these days there's really no need to run an entire app server in front of your database just to implement permissions.