API stands for Application Programming Interface which defines the way how it is possible to communicate with the system. In this article, I put focus on web technologies and their implementation in .NET.
Across many years, new design of APIs appeared in reply to new challenges, especially performance and implementation’s efficiency. Very first modern approach was RPC (Remote Procedure Call) proposed in 70s and implemented for the first time in 80s (source: Wikipedia). Inline with request-response concept, it was a milestone in distributed systems design and implementation.
In modern APIs, we may distinct 4 main technologies:
- SOAP (Simple Object Access Protocol)
- REST (REpresentational State Transfer)
- gRPC (google Remote Procedure Call)
- GraphQL (Graph Query Language)
Each of them have a bit different purpose and its support in .NET is various. SOAP, REST and gRPC are supported out-of-the-box, for GraphQL there is no default project template (by default). In case of GraphQL, 2 main options are available: HotChocolate and GraphQL.NET.
From historical perspective, SOAP is the oldest technology, rarely used for new projects, however it is worth to mention it as it is still available on the market, especially in legacy systems. GraphQL and gRPC are the latest “kids” of software development, however GraphQL has still poor support in .NET world. Also it is not well recognized by developers which does not make it real competitor to REST nowadays.
gRPC vs GraphQL
Therefore let’s dive into gRPC and GraphQL details. gRPC is designed for high performant, binary, bi-directional communication between microservices therefore is not good candidate for web clients. Web-gRPC ensures communication between web clients and backend services but it’s not the primary purpose of the technology, therefore before it will be used, all pros and cons have to be considered carefully. Considering GraphQL, it is human readable and easy to implement on client side. Also it gives a lot of features out-of-the-box (with many limitations).
gRPC
For .NET developers this is successor of SOAP (WCF) as .NET 5 removed its support. Communication is based on HTTP/2 protocol and it is using channels. The way how it is maintained, including closing, depends on language specific implementation. Also gRPC has embedded authentication and ensures encryption in transit (security by design).
gRPC is contract based (with .proto files). Protocol buffers is a language to describe data format. It is available in v2 and v3 however nowadays v3 is used the most often. Such descriptor is required as gRPC is binary protocol with full duplex stream support.
GraphQL
GraphQL was designed to query data represented in graph form. It has schema first approach similar to SOAP or gRPC and there is a lot of client’s generators across the web.
By default, GraphQL supports:
- queries – to retrieve the data
- mutations – to modify the data
- subscriptions – to ensure pub/sub via web sockets
Default communication method is POST (GET can be used alternatively) however the way how requests are send does not encourage GET. GraphQL has single endpoint with payload where query or mutation is specified with information to retrieve. Another aspect is sending information about the fields to return in a query and sending mutliple queries in single request (query batch).
The downside of multi-functionality embedded into GraphQL is limited number of supported technologies to resolve the problems (e.g. HotChocolate 10 in many features heavly depends on Redis and there is no alternatives).
Comparison
Besides gRPC, each solution is full cross platform (its limitation is HTTP/2 compatibility as prerequisite, older operating servers may not support it – e.g. IIS since version 10.0).
The table below is a comparison of selected features.
SOAP | REST | GraphQL | gRPC | |
---|---|---|---|---|
Created | Microsoft, 1998 (publicly available since 1999) | 2000 | Facebook, 2012 (publicly available since 2015) | Google, 2015 |
Purpose | Extensible, neutral, verbose, with bi-directional communication | Stateless, flexible, with no envelope | Efficient in frontend implementation | High performant, microservices communication |
Stateful/Stateless | Stateful or Stateless | Stateless | Stateless | Stateless |
Communication | ||||
Protocol | Any HTTP version, TCP/IP, MQ | Any HTTP version | Any HTTP version | HTTP/2 only |
Most often used format | XML | JSON, XML | JSON | Binary |
Request-response including stream | Request-response including stream | Request-response including stream | Request-response including stream | |
One-way/Two-ways | Two-ways | One-way | One-way | Two-ways |
Contract | Required (XML) | Optional | Required (JSON) | Required (proto defined) |
Browser support | Partial (with additional libraries) | Yes | Yes | Partial (through Web-gRPC library) |
Library support (in .NET) | WCF (till .NET 4.8) | Yes (with MVC/WebAPI) | External library | Since .NET 5 |
Additional features | + Caching out-of-the-box + Subscriptions (pub/sub) via web socket | |||
Pros | + Well known by developers + A lot of tools | + Well known by developers + A lot of tools + Flexible interface | + Easy to use by frontend teams + Caching out-of-the-box + Allow to receive only selected fields | + High performance + Well documented |
Cons | – Hard to maintain – A lot of data send (envelops) | – Contract is optional | – Not well documented – Not wide propagated | – Not (yet) widely used therefore not well known by developers |
Summary
Looking into the future, we may forget about SOAP and look forward on new solutions GraphQL and gRPC with all pros and cons of them. Also we need to remember that our solution is as good as libraries which we use. It is important factor in solution design. Altough we need to keep in mind that technologies evolves very fast and new solutions may appear very fast or current will be much improved.