One interesting comparison is that people use GraphQL as a frontend for REST APIs, but no-one in their right mind would consider doing the converse. If you go for a federated/microservices design, so one GraphQL server fronts for others, they can use a common specification of the API between the frontend and the microservices; this is less certainly true if the microservices are REST.
The pros and cons of each are:
GraphQL
Pro:
- provides fine control of returned data in avoiding unneeded traffic
- eliminates needing to go back to the well over and over for attached / “follow-on” data
- following from the above, it allows the software designer to provide excellent performance by reducing latency – each query specifies all the things it needs, and the GraphQL implementation can assemble and deliver it with only one client<->server transaction
- possibility of slow deprecations instead of versioned APIs
- it’s a query language
- introspection is built-in
Con:
- does not deal with caching (although there are now libraries that will take care of this)
HATEOAS / REST
Pro:
- caching is a well-understood matter
- relatively mature and well-understood
- lots of infrastructure for eg CDNs to spread the load
- very suitable for microservices
- file uploads are possible
Con:
- the “back to the well” problem
- not as rigidly specified
- each implementation of server and client(s) must make its own decisions
- querying is not standard