The struggle with it is more on the provider side. As you'd have horrible performance if you'd just rawdog an ORM onto it. The complexity of combining is where you'll struggle.
Last I played with GraphQL was with PHP. There is exactly one package that did GraphQL at that time. Where we had to define the models both in yaml and php.
Though this could probably be solved with dynamic building of the yaml.
Also last I checked the testing utils werent there yet.
Though it is really cool to be able to do supergraphs if you decide to do microservices.
Alternatives are json and protobuf. GraphQL kind of lands between big json blobs and protobuf's binary in size. Due to it's possible exactness. But that is wholly dependant on implementation.
- You value typing
- You have many relations and interrelations
- You have multiple clients with different needs
- Your org has a distinct divide between backend and frontend
- You need to stitch together data from many different sources (N microservices powering 1 api)
Ive had a lot of success with GraphQL and think the idea of providing an API schema instead of an API interface to be a beautiful addition to a systems design.
Also https://hasura.io has been a great accelerator when creating POC for products.
We used it at $lastJob and I thought it was a lot of complexity for what it offered. I had done a analysis of our gql stuff and maybe 20% of the time consumers took advantage of it.
Personally I'd just build a good RESTful API and not cram shit into responses that makes no sense. It isn't that hard to batch requests together, and imo I'd opt for KISS 100 out of 100 times.
I haven't worked somewhere that took 80%+ advantage of gql. Maybe its only Meta and a handful other capable places that really need gql, IMO.
Nowadays, I'm trying to keep things simple again and use jsonrpc. It's simple, versatile, portable and can even be used via WebSockets or raw socket protocols.
GraphQL is very useful, it removes whole classes of bugs. You can even use a Result/Either type where if you don't handle both the success and error cases, the GraphQL request won't even compile, so you can get type safety at both the client and the server while also not having to use purely TypeScript like with tRPC, allowing multiple clients like mobile and web. Pothos does this very well as an error extension [1], where, given the schema:
type Error {
message: String!
}
type Query {
hello(name: String!): QueryHelloResult
}
union QueryHelloResult = Error | QueryHelloSuccess
type QueryHelloSuccess {
data: String!
}
you can then query it with query {
hello(name: "World") {
__typename
... on Error {
message
}
... on QueryHelloSuccess {
data
}
}
}
If you forget `... on Error` the query will simply fail.
I should also add that most people use GraphQL incorrectly, to get the benefits of not over/underfetching, the Relay approach using fragments is the only viable way currently. Otherwise it's not too much better than REST. You define the exact data required for a specific React component in GraphQL fragments, then the Relay compiler will stitch those fragments together into one and only one request. This is a great (if long) overview on the problems Relay solves and why everyone else uses GraphQL incorrectly (then complain that GraphQL sucks) [2]. Hint, Apollo is not the way.[0] https://www.youtube.com/watch?v=yab6i9lrEv0
when you at the point where your REST looks like a mess - graphql would only make it worse
when your REST is still manageable - graphql doesn't bring anything radically new or intrinsically valuable to the table
Probably the only good fit is when you actually fetching a lot of _graph_ data.