OData and GraphQL (and the likes)
So, I recently migrated one of my home projects off of OData. And what did I migrate it to? Nothing. Or, well I suppose, nothing equivalent. I switched from OData and Controllers in .NET to use Fast Endpoints. I did not switch to a "competing" solution like GraphQL.
Frankly, I never got the point of GraphQL. I get the pitch. Only get back what you want, and then some helpers to connect services, etc... which is nice in theory. But, if you only need to solve the first problem, then OData can do that and do that more flexibly. And if OData doesn't meet your needs, you already need to craft the payload server side. Whether you spin it yourself or use GraphQL. And, if you're not reaching out to other services then I don't see where GraphQL gives you any gains.
If you ARE reaching out to other services and GraphQL makes your life easier then there is a bigger underlying problem; It is clearly too complex for you to spin your own solution to do this. And that should take higher priority over leveraging a solution which will automate things and thus take away control to a degree.
Am I being pedantic here? Sure. But I think my points are valid. GraphQL solves server side, the sorts of problems which OData allows you to solve client side. And you could always create custom actions or functions in OData to do that server side as well.
My falling out with OData was more around how much and how quickly it has changed. Most of the code was running. But everything threw warnings. It was probably my mistake and not OData. However, fairly similar code worked just fine on earlier versions of .NET Core without the warnings. On top of that, a lot of the improvements along the way in .NET Core and some other subjectively better solutions have made many of the problems which OData solved kind of not necessary.
I do prefer to have my endpoints more well defined, so something as open as OData isn't necessarily a bonus for me anyway. One thing I've learned along the way refactoring this project repeatedly is that more open interpretations make refactoring more difficult. Purpose built endpoints are a LOT easier (from both the Client and Server side) to migrate to new technologies later. In fact, this was the primary reason it took so long to make the leap away from OData. I had to refactor EVERYTHING. Now that the calls are more purpose built and not relying on OData query language under the covers, the API becomes a contract defined by me and not by another technology and that is what makes it possible for me to migrate more easily.
Sure, it is possible I could miss out on convenience functionality for deviating. But those conveniences are exactly what made the migration away from OData a pain. And not everything even played nice with OData to begin with.
I'm also reminded how OData and EF Core didn't play as well with CosmosDB as they did with SQL. Again, conveniences in one language start putting up barriers to migrating elsewhere.
These tools can be great for spinning up a project quickly. But I think that their purposes are too broad. They are opinionated in how they approach certain things and they take away some level of control. I'd rather solve the more fundamental issues they address in a targeted fashion, or on my own. If you rely too much on these, then projects become too beholden to them and their dependencies. They become more difficult to maintain and more difficult to evolve.
This is not to say that home brew solutions will always be better. I was a new developer once. And my solutions had their own way of becoming productivity sinks. But a point here;I enjoy refactoring my own code more than I do working around someone else's constraints. So, it is both more enjoyable and a better learning experience. It is also not always easy to identify overly broad solutions. For example, how is Fast Endpoints less broad than OData? Having used both I can point out a bunch, like the integrated query language in OData, and how it handles serialization and everything for selects, to the way it produces the $metadata document. But, 5-10 years ago I wouldn't have noticed any of that.
So, please don't see this as me standing on a soap box. At the end of the day this is just my preference and experience. Your priorities may vary. Maybe you don't maintain old projects and the small gains are more than worth it. Personally, I find code has a way of living well beyond its planned EoL and I end up getting pulled back more often than I would ever expect. Or, I want to rewrite a project to learn a language or framework. Cleaner architecture and more targeted dependencies make that easier.
And, in that sense I don't find GraphQL superior to OData. This was actually a huge reason why I was a proponent of KnockoutJS over things like Angular and React. Once you're in bed with something like Angular or React you are VERY in bed with them. Knockout was not a framework in the same sense. It was MUCH more targeted. It could move between most frameworks. And it was smaller. So, it had a smaller attack surface for vulnerabilities and was more probable that we could fork it and take over it if there was a vulnerability which wasn't going to get patched.
Inspired by that, I now try to write my UIs in whatever framework/language with as much code re-use as possible. By reducing my component count and relying on nested components or utilities I end up with less that I need to migrate when I try out something new.
Comments
Post a Comment