GraphQL represents a paradigm shift in the way that we think about requesting data on the frontend.
Previously (and mostly still) we make opaque calls to a backend REST API AND we kind of know what we’re getting back because we read some hopefully up to date swagger documentation or we talked to the backend engineer who sits next to us or however we got into this inner circle of API knowledge.
This doesn’t account for a lot of things though. Someone else may take over development of the application, all they see is a request, maybe that request returns a ton of information that isn’t used and that person wonders why. They’ll crawl through some code and eventually figure out how the API works and go about their day because that’s a not all that difficult thing to do.
The paradigm shift that GraphQL brings — and I’m sure this has been said in hundreds if not thousands of previous blog posts — is that that opaqueness is removed, what you see is what you get.
Here we can see we’re saying i want the hero, his friends, and his friends names. We know our frontends will get this data, or at the very least an object in this shape with some null fields.
For a long time I’ve thought about where the value in GraphQL lies, and there is no doubt in my mind that the type system and guarantees it provides are immensely powerful and endlessly helpful for API development and development on the front end, you know not only the shape but type of data you are getting.
Are there compromises we can make though? We have some APIs that are years old, some companies that are unwilling to invest in GraphQL as a technology, and a million other reasons we may not have a GraphQL server we can hit.
Should this rob us of our ability to have an expressive frontend development experience in which we can clearly see our components data needs colocated with the component itself? I don’t think so.
This is a problem that has kept me up at night for a very long time, and while this project is in its infancy I felt it would be better to share early and get feedback so maybe this silly idea in my head can become a real option as a middle ground between going all in on GraphQL and having opaque front end data handling. My goal is to use the expressive front end of the GraphQL query language while hitting any arbitrary backend, to have a new developer look at a component and say hey this is the data that’s supposed to come here and it’s not, now I can ask an informed question. I think I’ve made some really great strides in making this a real possibility.
If you look at the above code it really doesn’t look all that different from an Apollo HOC query. the difference is here there is no backing GraphQL server, the query data is being translated into calls to arbitrary API endpoints using the GraphQL parser on the string and then traversing the AST in order to gather the relevant information to make the calls. The paradigm here essentially calls for the top level items (person, post, todos) to be routes available on the
apiPrefix (or root of your server if apiPrefix is not provided)
From there we gather up relevant route parameters or query parameters and simply call the apis, gathering the data together into a single object, and passing it down into the wrapped component as props similar to what something like Apollo would do.
This essentially means that we can use GraphQL style querying on any route that we can hit, whether it is in our control or not. You can see an example of this in action here.
We make some tradeoffs, giving up some of the great benefits that come with a true GraphQL api including but not limited to types, better control over resolution, constructing the picked objects on the server instead of the client, and probably many more things that I don’t even know about.
In my probably biased opinion though this gives us easier access to the greatest thing GraphQL brought to frontend development. Expressive components with their data needs colocated right alongside. We shouldn’t be prevented from using this paradigm because we don’t have a GraphQL backend, we should be encouraging this style of component development wherever we can, and the nice thing is if you ever did move to a GraphQl backend the rewrite from this becomes vastly simpler then just constructed ad hoc API calls.
The work here is far from done and I’m positive there are many cases I have not yet covered but I’m convinced that I’ve stumbled upon something that could be great, and any feedback you have would be greatly appreciated (seriously any feedback, tell me I’m completely wrong). As I’ve said throughout this post and I’ll reiterate now I think GraphQL fundamentally changed the way we work with data on the frontend, if you can have an app backed by a GraphQL server I think you should, but I don’t think we should be limited by this and I think this project can make big strides in removing that limitation.
The code is on github here if you would like to look at it. If nothing else I hope this post makes you think about what we can do to make our frontends and their increasingly complex data flows easier to reason about. In my opinion that’s colocated GraphQL or GraphQL style queries but if there’s something better I would love to here that too.