I am seeing a lot of posts about how GRAPHQL is going to replace REST. From my experience, it might not happen. Rest replaced SOAP because of a content type. Rest supported JSON. That is the big milestone in terms of performance using data transfer. Data transfer has been reduced a lot using JSON instead of XML. Here REST and GRAPHQL are using JSON as data transfer. Both will support microservice architecture. The difference is GRAPHQL using queries as part of the post method for all types of CRUD.
Protocols and Verbs
REST is using the HTTP protocol. Directly we can access it from the browser. It provides HTTP verbs for a different type of CRUD operation. GRAPHQL is also using HTTP protocol. We can access it via the playground or simple post API from the postman. It provides different names like Query and Mutation of CRUD operation.
Authentication & Authorization
In Microservices architecture we can keep Authentication and Authorization at the gateway level or services level, or API level based on the business and performance. It will be the same for Rest and GRAPHQL.
Interservice Communication (Resolver)
Data fetching from multiple services. Multiple service calls can be done at the gateway using aggregation or we can add the logic at the corresponding services level.
If we are doing aggregation at the gateway, then the gateway becomes very heavy. The gateway should be a pass-through layer with authentication and authorization alone.
Some people will move the authorization to the corresponding services based on their needs. We can call one service from another one then microservice mesh with multiple API calls.
We can add a proxy to the microservices so the atomic operation will be done at the microservice. Other service calls based on business logic will be held at the proxy. In this flow, the number of proxies will get increased.
We can add a message system to communicate with other systems. It will be a loosely coupled and asynchronous one. In case we reverse the transaction again we need to publish the message. We shouldn't guarantee on the message order when it's getting processed. It will be the same for Rest and GRAPHQL.
Versioning
No need for versioning while adding new fields. Versioning will be required while removing the existing fields or updating the data type or changing the parameter from not mandatory to mandatory. People are claiming versioning is not required as part of Graphql. I do not completely agree with this point. As an API provider, I can provide a Graphql API to multiple partners. If I'm going to remove one of the fields so one of my partners will have corresponding client implementation so API will be work for him, how about the rest of my partners? They will look for the fields that will be required. Either we need to wait until all the partners consume the new implementation or we need to deliver a new API as part of the API provider.
URL
In REST we can have different resource name with corresponding HTTP verbs. It will describe what action API is going to do. In GRAPHQL we will have a simple POST API with different verbs like Mutation and query. Anyway, both will be the same in terms of functionality only difference is how the data is getting represent to the end-user.
Then where the difference is. It will be based on your business.
REST
We are building an application that will return the response as a big one. Consider IoT devices will return a lot of parameters as part of device status and configuration. In REST we can have simple endpoints like devices/status. It will return all the parameters. In terms of GRAPHQL, we need to pass the required parameter as part of the query. Then the query will become a big one. Some of the APIs will get called very frequently and the response will be a big one. In this case, we can use REST. We are having hashing in GRAPHQL so the query will get cached but resolving each field will have an impact in terms of performance how frequently we are calling and how big the response is.
GRAPHQL
We are building an application that will return responses from multiple services. Github will fetch user profiles, the repository they have access to, list of commits they have done. Using REST, we can aggregate the results from the microservices, but unwanted data is getting fetched also. Response size is getting increased, so data transfer is also increased. In this case, we can use GRAPHQL. It will serve the response based on responsive designs. People will claim using ODATA we can achieve the same kind of queries in Rest. We can, but it will be useful for a single entity. If we are having queries for multiple entities on multiple services, then query complexity will get increased. Then we need to write the separate logic to parse the query to corresponding services if we are enhancing the client without any breaking changes on the server-side. We can add GRAPHQL as a layer on top of the microservice or monolithic. It will increase the performance of data transfer between the client and the server by reducing the round trips.
GRPC
It's completely different from the above two. It uses the HTTP/2 protocol. HTTP/2 supports bidirectional and multiplexing. That is the big improvement in terms of performance compared to HTTP/1 which is what REST is using. It uses a binary protocol instead of JSON. Data transfer, as well as data parsing, will be reduced a lot. We can't access directly using a simple URL. We need a GRPC client to access it. Performance-wise it's providing better results compared to the above two based on my Azure app insights results. As an API provider, we can't provide GRPC to the partners. Because partners will have a different kinds of client implementation like rest and Graphql. Google is working hard to improve the GRPC for its simple client implementation like REST. Once it's completed it might be tough for the above two. Anyway, Google needs to do some parsing logic to covey the results from the binary to text one. It might get compensated with the performance. We can use GRPC for internal service communication on top of the REST or GRAPHQL. So, data will be getting fetched from different microservices instead of messaging systems.