Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Removed GraphQL recommendation from tech stack guide #718

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

pangolingo
Copy link

Not everyone at thoughtbot is convinced that GraphQL is the right choice for building APIs. It has complexity and footguns.

By removing this recommendation, we leave it open to a developer's best judgement.

pangolingo and others added 2 commits November 5, 2024 08:39
Not everyone at thoughtbot is convinced that GraphQL is the right choice for building APIs. It has complexity and footguns.

By removing this recommendation, we leave it open to a developer's best judgement.
@pangolingo
Copy link
Author

@MalcolmTomisin your PR #714 adds a new GraphQL recommendation. I'd love to hear your arguments for keeping GraphQL as our API recommendation.

@JoelQ
Copy link
Contributor

JoelQ commented Nov 5, 2024

Should we capture some of our thoughts on why (both for and against) in the commit message? That way there's a trail for those who check why we removed the recommendation?

@nickcharlton
Copy link
Member

Some summary/context around our thoughts:

This was inspired by a conversation started by @seanpdoyle, who posted a link to Why, after 6 years, I'm over GraphQl.

Several of us (including myself) agreed, after seeing GraphQL to be particularly difficult to operate in production (poor error handling, N+1 queries, overcomplicating the code in providers and consumers, among other things).

We also mentioned that some of the benefits — like types and autogeneration — could be gained from other solutions like using OpenAPI (née Swagger), which is much more common now than it has been.


Personally, I've always snarkily referred it to as SOAP, but with JSON!

I do wonder if we should instead be, "we prefer building RESTful APIs over using other solutions like GraphQL", then go on to explain some reasons why (including cases where GraphQL might be a good approach). What do others think?

@JoelQ
Copy link
Contributor

JoelQ commented Nov 5, 2024

I could see something like: "we default to REST APIs, but reach for GraphQL under the following scenarios ..."

@purinkle
Copy link
Contributor

purinkle commented Nov 5, 2024

All the opinions, so far, have come from Rails developers. I'd love to hear from our mobile developers, who this change would affect the most.

@louis-antonopoulos
Copy link
Contributor

First, as a former mobile developer, the biggest issue I ran into was people overusing GraphQL fragments, and there being no way to identify those situations other than carefully watching each network request or manually inspecting each query and each fragment and tracing down through the tree to realize, "Wait, why am I pulling all that data when I just wanted X?"

So instead of being a situation of, "The benefit of GraphQL is you only pull the data you need," it was the exact opposite, where our projects ended up pulling orders of magnitude more data than they needed, and a big part of why I would not reach for GraphQL.

Second, there are huge benefits to having a conversation between the mobile team and backend team in terms of creating valuable API endpoints, rather than the backend team creating endpoints more in a vacuum with the thought that the frontend will reach for what it needs.

These conversations can lead to database optimizations, refinements in what the UI is presenting, and so much more, but the back-and-forth conversation of "Here's what we need / How are you going to use it / What if we tried this instead" is invaluable.

@MalcolmTomisin
Copy link

MalcolmTomisin commented Nov 6, 2024

@MalcolmTomisin your PR #714 adds a new GraphQL recommendation. I'd love to hear your arguments for keeping GraphQL as our API recommendation.

From the perspective of client apps, I have to say GraphQL introduces a learning curve and can feel less ergonomic than a REST API in a simple client-server set up. It's a footgun for most CRUD use cases where REST is intuitive. Although there are rare scenarios I have found GraphQL wieldy, e.g when building dashboards with complex combination of data from multiple APIs, with GraphQL the data is presented to me in a single interface rather than the complex API calls that would be required in a REST style API.
However, you trade off contextual clarity for simplicity in querying with GraphQL. Another developer comes on to the same codebase and they are head scratching trying to understand "why do I have this value?" as opposed to a complex REST API call where the relationships and rationale are often clearer. In contrast, GraphQL abstracts these relationships and rationale behind schemas and resolvers.

@rakeshpetit
Copy link
Contributor

rakeshpetit commented Nov 6, 2024

I agree with folks on the pain it causes on the server when multiple queries, (n+1) queries, etc are made by the front-end using GraphQL. We have faced this problem for our client a few times.

From a client app perspective, GraphQL has some advantages such as

  • Rigid Schema kept in sync with the server.
  • Easier to version APIs without breaking client apps
  • Fetching what's needed
  • Nested data fetching in single request and so on.

These advantages are useful for specific projects but REST APIs when combined with TypeScript provide similar schema rigidness. Rest of the advantages are not applicable for all projects and hence REST APIs can be our default way to expose data to a mobile client.

Overall, instead of removing the entire "API" section, I would reword it to "We recommend using REST APIs" like Joel mentioned.

@pangolingo
Copy link
Author

I'm going to be on vacation for a few weeks. If anyone else would like to pick up this PR and compile some of the suggestions from folks, please do!

@JoelQ
Copy link
Contributor

JoelQ commented Nov 13, 2024

Separate from GraphQL specifically, it sounds like something we like on both the back-end and front-end is having a schema for the API? GraphQL has this by default, REST APIs can have one through a variety of means. Maybe we should add a recommendation to make sure APIs have a schema in place?

@nickcharlton
Copy link
Member

Maybe we should add a recommendation to make sure APIs have a schema in place?

I think so, too. Do you fancy opening a PR for that? I'd be happy to as well.

Something I think is worth considering for that: Do we have a general preference for tools for doing that? I think something in the guides which provided specific direction there would be great (and also would make a good blog post!).

@JoelQ
Copy link
Contributor

JoelQ commented Nov 13, 2024

@nickcharlton done in #719

@JoelQ
Copy link
Contributor

JoelQ commented Nov 13, 2024

Easier to version APIs without breaking client apps

@rakeshpetit I'd love to hear more about this. My understanding is that GraphQL is explicitly versionless

@rakeshpetit
Copy link
Contributor

rakeshpetit commented Nov 20, 2024

My understanding is that GraphQL is explicitly versionless.

I think we both might have meant the same things. Unlike a REST API where it's common to use V1, V2 and so on for versioning, we do not need to do that on GraphQL. Schema depreciations allow clients to seamlessly transition between old and new APIs.

An example:

query {
  listUsers {
    name
    age
  }
}

If we decided to replace age with birthDate in the future, we can mark it as deprecated like below and add the new field in the same query. Old clients will continue to consume the same query and not have any knowledge about birthDate as it is not part of the query while new clients can remove age and replace it with birthDate. The use of @deprecated values might generate warnings on the Front-end although not sure about this.

type User {
  id: ID!
  name: String
  age: Int @deprecated(reason: "Use birthDate instead")
  birthDate: String
}

@nickcharlton
Copy link
Member

@rakeshpetit, do you have any thoughts of an example where you definitely couldn't do that in a versioned RESTful API?

If we added a new field (and didn't remove the existing one), this is something I would do with a REST API. As long as you're not breaking the existing contract by removing behaviour, that's generally acceptable, imo.

(Deprecation warnings are a bit trickier, but not impossible.)

@JoelQ
Copy link
Contributor

JoelQ commented Nov 21, 2024

So this becomes a comparison of schema systems rather than general API design approach. There is no single schema system for REST APIs like there is for GraphQL so comparisons will vary. Looking at one popular choice: JSON-schema can also do deprecations of properties.

I wonder if this is more about the tooling than about the tech itself? The JS world (or maybe even just the React world?) has better GraphQL tooling than generic REST API tooling?

@rakeshpetit
Copy link
Contributor

rakeshpetit commented Nov 21, 2024

do you have any thoughts of an example where you definitely couldn't do that in a versioned RESTful API?

Good question. I think a versioned REST API can do everything that the deprecated achieves while using GraphQL. The complexity (both server side and client side) is higher when it comes to versioning using REST API whereas with GraphQL the server side complexity more or less is similar but it is much easier on the client side.

If we added a new field (and didn't remove the existing one), this is something I would do with a REST API. As long as you're not breaking the existing contract by removing behaviour, that's generally acceptable, imo.

That's true. The example I added was basic involving just GraphQL Queries but maybe we can extend the idea with GraphQL mutations (POST, PUT, DELETE) too 🤔

Joel's thoughts on this just being about schema and tooling makes a lot of sense. I do wonder why the community mentions that it's easier to version GraphQL APIs compared to REST, if it's all about schema and tooling.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants