I started playing around with GraphQL around 2 years ago. I was stunned by the power of the technology. Especially:
- The ability to dynamically fetch different attributes at runtime without having to change the API itself
- Speed of the fetches, even with large datasets
- Subscriptions - Ability for the API to behave as a event-driven subsystem by itself.
Since then, I have done some research about it and presented some offensive and defensive research at various conferences and online events. One of my favorite talks was at AppSec California last year
I decided to "eat my own dog food" and build something in GraphQL. I was always looking to make our "threat-modeling-as-code" framework as an API. I decided to go with GraphQL instead of the typical REST API.
In fact, I blogged about my experience with that in this post.
Today, I have realized that this was a wrong decision and I will be reverting to REST API for ThreatPlaybook. The reasons for this:
- I wrote ThreatPlaybook's API with Python and
graphene, a popular Python GraphQL library. Mongo is the primary database that I am using for ThreatPlaybook. Some issues that I faced with Graphene:
- While it works well enough, its very sparsely documented, especially complex use-cases. I had to figure out a lot of stuff on my own, which was hard and time-consuming
- The Mongo Library for GraphQL in python was very basic. In general, I feel that NoSQL databases dont fit with GraphQL (explained later)
- Performing Aggregations, etc with Mongo, required me to go back to REST, making it very frustrating for me
- With GraphQL in general, I have constantly run into the following issues:
- Error Handling sucks. With REST API its nice to be able to handle errors with status codes, etc. With GraphQL you have to deal with nested JSON, making things a little more complicated. This was made worse by the fact that I was building a CLI for the GraphQL API and handling errors became a massive PitA
- I think GraphQL doesnt lend itself well to NoSQL Databases. I saw this with Mongo and DynamoDB. I see that it works better with traditional RDBMS, where there's clarity around schema and relationships a lot more than with NoSQL DBs. The fact that popular projects like Hasura and Prisma are RDBMS support should tell you something.
- As an extension to the previous point. I feel that GraphQL is great as an API for consumption rather than handling transactions and CRUD operations. For instance, I feel its much better utilized when you have a lot of data in your RDBMS and want to provide an API Interface to be able to query that dataset dynamically, rather than edit/modify it.
I am rewriting ThreatPlaybook's API in REST now and should be done by the end of the month (April 2020). And other than for security research and client work, I am not planning to use it in any of my projects.