networking -- graphQL, GRPC
what is graphQL
GRAPH QUERY LANGUAGE
if we want a list of all continents, all countries, all languages
using restAPI we will make 3 API calls and get the data, and convert all those data to required format in the client
this kind of heavylifting on client is removed with GRAPHQL, here we just make one request to graphql server, then tat makes 3 requests to continents,countries,languages API’s gets data, and converts tat to required format and gives tat data to client

the data will be represented in the form of graph and GRAPHQL , queries and gets required data easily from this graphs
eg: continents have countries and countries have languages so, all of this data is like a graph

in 2012 facebook —- came up with this, in 2015 it was made —opensource
here client can decide what info it can get from server, in any reqd format
https://studio.apollographql.com/org/lakshmiprasannapinnams-team/graphs —- here we can play with graphQL queries

here see we have created a single query, where we wanted continents,countries,languages with name,code —- and we get reply also in same way —-
continents can have much info like number of population, staplefood etc.. we dont need all tat we need name,code and we got tat only
GRAPHQL benefits
avoids over-fetching —- reduces fetching all useless info
- results in increased performance of app
avoids under-fetching [not getting all required data in a single request]
better performance with mobiles
more efficiency
getting hierarchial structured data as we need on client
strongly typed —-
only the existing keys in individual tables are considered, if we type random name it will throw error
no need to introduce any typescript for strong typing
Introspection : for RESTAPI we have to create some documentation — like for this API this is response format [using SWAGGER]
- but for graphQL automatically the documentation is created see in below img
we have realtime capabilities using subscription[websocket kindof experience] in graphQL
The client initiates a subscription query specifying the event to track (e.g., data creation or updates).
A WebSocket connection is established for persistent, two-way communication between the client and server.
The server listens for the specified event and publishes updates when it occurs.
Subscribed clients automatically receive the relevant updates in real time.
The client processes the updates and reflects them in the UI for a dynamic experience.

see this image here with our query automatically, countries are mapped to continents and languages are mapped to countries and we got results as per tat
in GRAPHQL allmost all request we make are POST requests
at highlvl graphQL also uses HTTP REQUEST, HTTP RESPONSE,HTTP HEADER, HTTP STATUSCODES structure itself
rest v/s graphqL [vvvimp interview qn]



to get anything we use query in GRAPHQL
to create,update,delete etc… we use mutation in graphqL
versioning
in RESTAPI versioning is crucial to manage updates as new features are added or old ones are modified
The version number is included in the API endpoint's URL. This is straightforward and easy for clients to identify.
Example:
https://api.example.com/v1/resourceorhttps://api.example.com/api/v2/resource
in GRAPHQL we have @deprecated tag says tat somefield is used in a table previously but not now —- no versioning here

client of graphQL server can use anything to get data FETCHAPI, or any advanced libraries for more capabilities like caching etc…
using many libraries/ combination of libraries we can build a creator/graphQL server
https://graphql.org/community/tools-and-libraries/?tags=javascript —- here we can see all libraries in all languages tat graphqL supports from server,client side
now for practice we are using Apollo server, Apollo client
building blocks

schema:
eg: for a country wat keys are needed, like name,code,population etc.. are mentioned here
note: ID is inbuilt type just like String in graphQL
types in graphQL are scalar/builtin ; customTypes
all graphQL schemas are written in SDL language
resolver:
these are the functions on the server which help us to get/update/create/delete our data, when we use queries/mutations on client we use these resolvers
parametres of resolver fn:
parent info — parent associated with current part of schema —- example: in below image we need countries associated with a particular continent , so if we are fetching array of countries, in its parent info continents is present

args : filters applied by client
context:
any request entering graphQL server goes to many resolvers,functions,logic etc… before it responds,
if some common info has to be shared among all these resolvers/fns through which request goes we use context
info: any info related to execution of query

How Requests Flow Through Express and GraphQL
Request Reaches Express: When a client sends a request to
/graphql, the Express server receives this request.Route Matching: Express checks if any defined route matches
/graphql. If it does, Express sends the request to the function handling that route, which is the GraphQL server in this case.GraphQL Server Handles the Request: The GraphQL server receives the request, interprets the query, and sends back the requested data.
creating graphQL app with apollo server and client
https://www.apollographql.com/docs/apollo-server/getting-started
npm init --yes —→ create pkg.json
npm pkg set type="module" ————→ sets type in pkg.json to module , so tat we can use import instead require keyword
npm install @apollo/server graphql ————- installs apollo server
we need to contruct typedefs and resolvers in 2 different files and import it in index.js[which is our express app] to use them as arguments for apollo server
query,mutations also comes under typedefs
npm i nodemon —- in start script use nodemon to start express server
on running example query on localhost we can see a POST request with examplequery is sent to expressapp in network tab, left click on that request and click on that and copy it as fetch


paste the fetch query in console and convert output to json and see wat data we are getting
in below image see the body of request there we can see the query we have used

check the data we are getting

apollo client is just like a wrapper on top of fetch , which gives us more capability apart from fetching data
https://the-guild.dev/graphql/apollo-angular/docs/get-started —- docs for apollo-client
gRPC:
RPC —- remote procedure call
gRPC — google remote procedure call — opensource
gRPC is a framework built on top of RPC
RPC —- from your client , we can directly call the fns written on server which is a machine sitting at another place using RPC
used for , very performant and highly effective communication b/w 2 systems
here we can do loadbalancing, healthchecks, tracing , authentication etc..
how gRPC works?
lets say we have 2 remote servers, one is requesting for some info [so lets call it a client]
how client is executing fn written on server?

in clientstub and serverstub massaging/transformation of data happens
the entire communication on above diagram happens on HTTP2 protocol, so here we get all benefits of HTTP2 protocol
like compressed headers etc…
here we will have single long lived communication with only one single TCP handshake [streaming of data happens here] —- for execution of a function — and we have bidirectional streaming in tat particular connection [not like websockets] — imp point
for another fn call, another connection happens

protocolBuffer
it is developed by google
in case of RESTAPI we send and getback JSON data
gRPC uses Protocol Buffers, a platform-neutral and language-neutral interface definition language (IDL), to define service contracts and data structures. In a
.protofileJSON is always sent in a serialised/stringified version in RESTAPI b/w systems
here in gRPC communication happens in Binary format — so things are faster here — even serialisation and deserialisation are faster here
here in .proto file we write interface of protobuf , not in .json file
currently we use proto3 version
when 2 machines whose code is in different languages are communicating, in .proto file we write human readable code
Once the
.protofile is defined, you use a compiler to automatically generate code in the languages your other server usesjson.stringify which is used in RESTAPI, can be used to serialise & deserialise data b/w servers whose code is in same/different languages, but in gRPC we use protobuf serialisation which converts data to binary format b/w 2 servers whose codes are in different language

benefits of protobuff
binary code can be deserialised and executed on small machines too very easily , so very useful for mobiles
this is very faster and transport of binary data is faster
coding part:
we connect our browser client to a express server [which is a server] — here communication happens using REST API
then our express server is connected to other servers using protoBuff, the other servers will be gRPC

https://grpc.io/docs/ — refer this official gRPC documentation
sequence numbers importance
Unique Field Identification
Each field in a message is assigned a unique sequence number. When a Protocol Buffers message is serialized, these numbers are used as keys in the binary format, not the field names. This keeps the messages compact and efficient.
message Customer {
reserved 4, 5; // Prevent using sequence numbers 4 and 5
reserved "old_field_name"; // Prevent using an old field name
string id = 1; // Sequence number is 1
string name = 2; // Sequence number is 2
int32 age = 3; // Sequence number is 3
}
Guidelines for Sequence Numbers:
Use numbers 1 through 15 for fields that occur frequently, as these require fewer bytes in the encoded message.
Use numbers 16 and above for less frequent fields, as these require more bytes in the encoded message.
Never reuse or reassign sequence numbers for different fields in the same message.


RESTAPI JSON data:
Advantages:
Easy to debug and understand because JSON and XML are human-readable.
Works over standard HTTP/HTTPS.
Disadvantages:
JSON/XML payloads can be larger in size, making them slower to transmit.
Parsing these formats takes more processing time compared to other compact formats.
gRPC protoBuf :
gRPC uses Protocol Buffers (Protobuf), a compact, binary serialization format, to encode data.
Protobuf messages are smaller and faster to serialize/deserialize compared to JSON or XML.
we can generate code in any language, so it is language agnostic
gRPC —- below makes it more performative(10x faster) compared to RESTAPI
protoBuf
BINARYDATA
multiplexing
header compressing
these all above comes due to HTTP2
streaming: here in gRPC, we can allow
only client to server streaming
only server to client streaming
bidirectional streaming
Disadvantages:
Not human-readable, making debugging more challenging without tools.
Requires Protobuf schema files to define the data structure.
limited browser support [browser cant communicate well ,with gRPC,so we need a express server in b/w]
no edge caching, [coz of post method which is internally used, between express, gRPC servers]
restAPI
How It Works Across Languages:
REST APIs typically use HTTP/HTTPS as the transport protocol and JSON as the data format.
JSON is language-agnostic and widely supported by almost all programming languages. Libraries for handling JSON exist in Python, JavaScript, Java, C#, etc.
REST APIs rely on simple HTTP methods (GET, POST, PUT, DELETE), which are universally supported across platforms.
Advantages for Cross-Language Communication:
Ease of Use:
JSON's human-readable format simplifies debugging and testing.
Developers don’t need special tools or libraries to parse JSON or make HTTP requests.
Broad Compatibility:
- Any language with basic HTTP and JSON support can interact with a REST API.
Limitations:
Parsing Overhead:
- JSON serialization/deserialization is text-based, making it slower and less efficient compared to binary formats.
Loose Typing:
- Lack of strict schemas can lead to errors if the client and server are not synchronized on the data structure.
2. gRPC:
How It Works Across Languages:
gRPC uses Protocol Buffers (protobuf) for serializing structured data.
The protobuf schema defines the data structure and service methods in a
.protofile.Language-specific code is generated from the
.protofile (e.g., Python, Java, C++, Go), ensuring consistency.gRPC relies on HTTP/2 for communication, enabling advanced features like multiplexing and streaming.
Advantages for Cross-Language Communication:
Strong Typing:
- Protobuf enforces a strict schema, minimizing misunderstandings about data structure.
Efficiency:
- Protobuf's binary serialization is compact and faster than JSON, reducing bandwidth usage and improving performance.
Tooling Support:
- gRPC provides built-in tools to generate language-specific bindings, making client-server interactions consistent and error-free.
Limitations:
Setup Complexity:
- Requires generating code in the target language from
.protofiles, which can be cumbersome for simple applications.
- Requires generating code in the target language from
Less Human-Readable:
- Binary format is harder to debug without specific tools.
Dependency on Libraries:
- Protobuf and gRPC libraries must be available for the target language.
Why One is Better than the Other:
REST is better if:
You need simplicity, human-readability, or a lightweight setup.
You're building applications where clients may change frequently or are implemented in less commonly supported languages.
gRPC is better if:
You prioritize performance, strong typing, or advanced features like bidirectional streaming.
Your team is working in a controlled environment where generating language-specific code is feasible.
Conclusion:
REST's flexibility and ease of use make it suitable for most general-purpose applications, while gRPC shines in high-performance, type-safe, and structured environments. Choose based on the complexity and performance requirements of your project!