Skip to main content

Command Palette

Search for a command to run...

networking -- graphQL, GRPC

Updated
11 min read

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

    • 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 .proto file

  • JSON 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 .proto file is defined, you use a compiler to automatically generate code in the languages your other server uses

    • json.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:

  1. Use numbers 1 through 15 for fields that occur frequently, as these require fewer bytes in the encoded message.

  2. Use numbers 16 and above for less frequent fields, as these require more bytes in the encoded message.

  3. 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:

  1. 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.

  2. Broad Compatibility:

    • Any language with basic HTTP and JSON support can interact with a REST API.

Limitations:

  1. Parsing Overhead:

    • JSON serialization/deserialization is text-based, making it slower and less efficient compared to binary formats.
  2. 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 .proto file.

  • Language-specific code is generated from the .proto file (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:

  1. Strong Typing:

    • Protobuf enforces a strict schema, minimizing misunderstandings about data structure.
  2. Efficiency:

    • Protobuf's binary serialization is compact and faster than JSON, reducing bandwidth usage and improving performance.
  3. Tooling Support:

    • gRPC provides built-in tools to generate language-specific bindings, making client-server interactions consistent and error-free.

Limitations:

  1. Setup Complexity:

    • Requires generating code in the target language from .proto files, which can be cumbersome for simple applications.
  2. Less Human-Readable:

    • Binary format is harder to debug without specific tools.
  3. 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!