Communication
Network protocols are key part of systems today as no system can exist in isolation and they need a way to communicate with each other. There are various protocols such as HTTP, TCP, UDP, RPC, REST, GraphQL, etc to have a standard way of communication between two devices.
HTTP
HTTP is a method for encoding and transporting data between client and server. It works on a request/response model where each device issues a request to another device to which the other device responds. It is a self-contained, stateless prrotocol that allows it to flow through many intermediate routers and server that can perform various operations such as caching, encryption and compression.
A basic HTTP request consists of method and response endpoints
| Method | Description | Idempotent* | Safe | Cacheable |
|---|---|---|---|---|
| GET | Reads a resource | Yes | Yes | Yes |
| POST | Creates a resource or trigger | No | No | Yes if response contains freshness info |
| PUT | Creates or replace a resource | Yes | No | No |
| PATCH | Partially updates a resource | No | No | Yes if response contains freshness info |
| DELETE | Deletes a resource | Yes | No | No |
reference: Everything you need to know about HTTP
TCP
Transmission Control Protocol (TCP) is a connection-oriented, reliable and ordered protocol used for transmitting data over an IP network. It establishes a connection between a sender and receiver before data transfer begins and ensures that each data packet arrives in correct sequence without errors via sequence number and checksum fields for each packet and provide mechanism for retransmission of lost packets and flow control to manage network congestion. TCP is useful for applications that require high reliability but are less time critical. Some protocols implementing TCP are HTTP, SMTP, FTP, SSH, etc.
UDP
User Datagram Protocol is a connectionless, simple transmission model that doesnt guarantee the data will reach it destination but is considerably faster than TCP. It does this by no handshaking protocol, no ordering, no flow control, no retransmission or no acknowledgements. It takes data from application layer, attaches a small header and sends it directly into the network as a datagram. It is ideal in situation where speed and low latency matter more then perfect accuracy or where the application layer handles its own error checking such as realtime streaming, VOIP, online gaming, domain name system and network management (dhcp and snmp).
RPC
Remote procedure call is a binary protocol and technique that allows a program to execute a subroutine or procedure on another server over a network, without having to explicitely code the details for that network interaction. RPC relies on an architectural pattern involving stubs and runtime. The stubs acts as proxies, masking the complexity of the network. Its execution procedure is as follows:
- The client makes a standard local procedure call to the client stub
- The client stub marshalls/serializes the function params into standardized network message.
- The client stub passes the message to the local RPC runtime which sends it over to the network to the remote server.
- The server RPC runtime receives the packets and passes them to the server stub.
- The server stub unpacks the parameters from the network message. This is called unmarhsalling/deserialization.
- The server stub calls the actual local procedure on the server machine.
- The process reverses to send the output back
RPC portmapper is the process where a client discovers the server's network address and the port number. Some popular rpc implementations are: gRPC, RMI (remote method invocation), json-rpc, xml-rpc, etc. R
REST
Representational state transfer is an architectural style used for designing networked applications. It relies on a stateless, client-server protocol and treats everything as a resource. There are 6 guiding constraints of rest:
- Client-server architecture: the client (frontend) and the server (backend) are completely separated and isolated and communicate with each other
- Statelessness: every request from a client must contain all the information necessary for the server to understand and process it.
- Cacheability: server responses must define themselves as cacheable or non-cacheable
- Layered system: client cannot actually tell what it is connected to such as server, load balancer,etc enabling easy scalability and security updates without updating client code.
- Uniform Interface: It requires a standardized way to interact with the server:
- Resource Identification: Resources are identified using unique Uniform Resource Identifiers (URIs/URLs)
- Resource Manipulation Through Representations: When a client holds a representation of a resource (like JSON data), it has enough information to modify or delete the resource on the server.
- Self-descriptive Messages: Each message includes enough information to describe how to process it such
content-type. - HATEOAS (Hypermedia As The Engine Of Application State): The server response should provide links to other actions the client can take from its current state
- Code on Demand (Optional): Servers can temporarily extend client functionality by transferring executable code (like JavaScript applets or compiled components
REST is focused on exposing data. It minimizes the coupling between client/server and is often used for public HTTP APIs. REST uses a more generic and uniform method of exposing resources through URIs, representation through headers, and actions through verbs such as GET, POST, PUT, DELETE, and PATCH.
| RPC (Remote Procedure Call) | REST (Representational State Transfer) |
|---|---|
Action-centric: Focused on executing functions or procedures (e.g., createUser()). | Resource-centric: Focused on data entities and resources (e.g., /users). |
| Tight coupling: The client must know the exact function signatures and interfaces defined by the server. | Loose coupling: The client and server interact through standard, uniform HTTP interfaces. |
Uses HTTP primarily as a transport mechanism (often relies only on POST). | Uses HTTP verbs semantically to define actions (GET, POST, PUT, DELETE). |
| Often uses highly efficient binary formats (like Protocol Buffers) or text formats like JSON/XML. | Primarily uses text-based formats, most commonly JSON or XML. |
| High performance: Lower overhead and smaller payload sizes make it ideal for internal microservices. | Moderate performance: Higher text overhead, but benefits from built-in HTTP caching mechanisms. |
| Supports native, bi-directional streaming (client-to-server and server-to-client). | Typically limited to unidirectional request-response cycles. |
GraphQL
It is an opensource query language and server side runtime for API's designed to give clients exactly the data they request, avoiding ineffeciencies of traditional REST endpoints. It solves the problem of overfetching and N+1 problem as client requests for the data it requires. It has three components:
- Schema: The contract between the client and the server, written in schema definition language. It explicitely defines the types of data available and how they relate.
- Query: The request structure sent by the client, which mirrors the exact shape of the expected json response.
- Resolvers: Server side functions responsible for fetching the data for specific fields. The parent resolver can fetch the whole object from db and the graphql engine filters out unrequested fields. This can be optimized using look ahead at the incoming query structure to select only specific columns from the database, preventing database-level overfetching.
| GraphQL | REST (Representational State Transfer) |
|---|---|
Single Endpoint: Accesses all data through a single gateway (usually /graphql). | Multiple Endpoints: Uses unique URIs for different resources (e.g., /users, /posts). |
| Client-Driven: The client defines the exact shape and fields of the data it wants. | Server-Driven: The server defines the fixed structure of the data returned per endpoint. |
| No Over/Under-fetching: Eliminates wasted bandwidth and the N+1 database round-trip problem. | Prone to Over/Under-fetching: Often returns too much data or requires multiple requests for related data. |
| Strictly Typed: Relies on a predefined schema and type system (SDL) to validate queries. | Weakly Typed: Data format is contractless, relying on documentation rather than built-in validation. |
| Smart Resolvers: Processes fields independently, filtering data or selectively querying the database. | Static Controller Routing: Maps requests directly to standard database query methods. |
| Real-time Subscriptions: Supports native, persistent real-time updates using WebSockets. | Stateless Request-Response: Relies on independent HTTP requests (requires polling for real-time data). |
