3 Communications technologies that every developer must know

Paulo Cardoso
10 min readOct 30, 2023

--

In this article, I bring to you the 3 most popular communications technologies that I’ve been in touch with during my career and think are very relevant to every developer. A quick look around these 3 and a bit of tutorial touch.

In my 10 years acting as a software engineer these are the most frequent communication technologies that I've been in touch with. All these 3 technologies are very important to know in order to better attend to your client/product.

Here's my curated list of it.

REST

By far the most popular, every single company that passed had at least one service using this communication style. REST stands for Representational state transfer, The concept is very simple, it uses a client-server communication model and relies on HTTP methods (GET, POST, PUT, DELETE) for the interactions.

Basically, the client will send one request to the server and the server should deliver the response.

Data flow of REST architecture

Important to mention that this model is synchronous, so your request will be "blocked" until you receive the server response.

Why is so popular?

REST APIs are very popular because are very versatile, and very simple to implement. Furthermore, here are some other points that contribute to this popularity:

Compatibility, REST is on top of HTTP, which means that REST APIs can be accessed using standard web technologies.

Flexibility is easy to work with JSON, XML, or any other type of data response.

Industry and Community created a wealth of resources and tools available for developers to learn and implement REST services, making it easier for new and experienced developers to work with REST.

Common challenges:

“It’s not all sunshine and rainbows.”

  • API Versioning — Once one endpoint is published and you have services consuming this endpoint shouldn’t be invalidated. Because of that, is very common to see payments API for example with multiple API’s versions. So, if you decide to use this approach, be prepared to deal with the versioning.
  • Long response time — If your application is responsible for delivering data for more than one device, it is very easy to lose control of the amount of data in one endpoint. You can suffer from overfetching or either underfetching.

Overfetching and Underfetching

Imagine that you have one API that provides user information for one desktop dashboard and the same endpoint will provide data for the mobile app of that dashboard.

Probably the mobile app will receive more data than necessary. Then you will need more time to process all that unnecessary data. In that scenario, you may need something to act as a middleware to prevent this from happening.

Over time, the volume of returned resources may grow, leading to an escalation in both the load and response times.

  • Complex queries — To deal with complex queries, filtering, and searching can be challenging with REST, as it typically relies on simple URL parameters.

Is not very difficult to find endpoints like this one:

GET /api/articles?author=John+Doe&publishedAt=2023-01-01&category=Technology

As you can see, the HTTP query param has been used to filter the results.

  • author=John+Doe filters the articles to those written by the author "John Doe."
  • publishedAt=2023-01-01 filters the articles published after January 1, 2023.
  • category=Technology filters the articles belonging to the "Technology" category.

Depending on where you are doing this request, preparing just the URL can be a challenge. Back in the day, 2015 I think, I was trying to create one request lib using C, and was a big headache!

WebSockets

Back in 2014, I was challenged by my professor to develop one basic chat message application, and while I was developing the backend I quickly realized the limitations of using the traditional REST API approach. Questions like:

- “How can I know if there’s a new message?”

- “What is the best time to make a new request to the server to know if there’s a new message”

- “What if I check every single second? is that good for the server?”

Then, I found the Socket.IO library and the WebSocket concept and it was a game changer!

To understand how WebSocket works, you need to know how HTTP works, and for that, I will try to explain to you in the most summarized way possible.

How does HTTP work?

This was actually one interview question that I had to answer another day

Ok, the first thing you need to understand is, that every time that you visit one page on the internet, your computer is using HTTP to download the page. Here is how:

Step 1: Access the designated URL in your web browser.

Well, I think there are no surprises here if you’re reading this article, you probably know that.

One important thing to take note of is, that your browser is able to handle multiple protocols, in that case, we are using the http:// but you can also navigate into different protocols such as ftp:// or access your file:// system

Hypertext Transfer Protocol (HTTP)

Step 2: Browser obtains the IP address.

1987, Guns N’ Roses, Sweet Child of Mine “Where do we go now?”

Ok, now it’s time to know where that page is located. We need to get the IP address of the server that has the page. For that, the browser asks for the Domain name server (DNS). What is the IP for that domain name (example.com)?

Resolving the domain name

Step 3: Browser sends the HTTP request to the server

Now the browser knows where to send our request, and then he sends the HTTP request to the server.

GET /index.html HTTP/1.1
Host: www.example.com

Step 4: Server sends the response

If all goes well, the server will send a response with important pieces of information about the page, such as content size and type, as well as the page content itself.

Pay attention to this image, I will need you to remember this later.

HTTP — Request, Response model
The request, response HTTP model.
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Content-Length: 208
<!DOCTYPE html>
<html>
<head>
<title>Example Domain</title>
</head>
<body>
<h1>Example Domain</h1>
<p>This domain is to be used for illustrative examples in documents.</p>
</body>
</html>

Step 5: Browser renders the response

Last but not least, the browser renders the page.

Example page rendered

Now, that we are on the same page, the “problem” with this model in special steps 3 and 4 is once you send one request and the server responds, the communication is over.

If you need to get something more, or if the server needs to notify you about some new event, you need to create a new request and wait for a new response.

Bi-Directional Full-Duplex channels

To solve that, WebSockets uses one Bi-Directional Channel over a unique TCP socket (Transmission Control Protocol) Full-duplex. Once the communication is established with the server, both can communicate with each other without one waiting for the other.

Then, with that new channel, the messages between the client and the server can be exchanged in real time.

Remember the challenge my professor proposed? Guess what tool I used.

GraphQL

Developed by Facebook in 2012, but only went public in 2015, GraphQL is one of my favorite tools when handling multiple types of devices. A concise definition of GraphQL is that it’s a query language for APIs and a runtime for executing those queries by leveraging existing data.

This one uses HTTP as well and works based on a simple concept, you will send one query to the server with everything that you need, and the server will only retrieve the data that you have asked for.

The essentials

  1. It allows the client to define precisely the data it requires.
  2. It simplifies the process of consolidating data from various origins.
  3. It employs a data type system for data description.
GraphQL representation

Let's go through the fundamentals without looking like boring documentation.

Schema and Types

The GraphQL Schema is the way to represent your model, which gives you the kind of object that you can fetch, it also describes the data types of fields.

type Character {
name: String!
appearsIn: [Episode!]!
}

In this example from GraphQL Docs, the first line type Character we describe a new Object type and down below the fields that you can query. The exclamation mark at String! , means that the field name is not nullable.

The array at appearsIn: [Episode!]! says that in our Object type Character we have an array of Episode.

There are so many things you can do on your Schema, such as Interfaces, Enumeration types, Scalar Types, Input Types, and Union Types.

I will not cover all here, I think this is not the objective here. But I promise to make something just around that.

Queries, Mutations, and Subscriptions

GraphQL is focused on data fetching, after all, it is a query language. However, the Facebook team needed something more powerful, able to modify information on the server when necessary. Beyond the traditional queries, they added Mutations and Subscriptions.

One thing that I think is very important to know is, that all GraphQL queries are sent using HTTP POST requests and the queries went through the body of that request. You can check the payload and the response at the network tab on your browser.

Queries

To get data from the server that uses GraphQL you will need to know how to use query.

query {
users (id: 123) {
name
image
}
}

The query has a structure very similar to a JSON, and as I mentioned before, the client is able to have control of the data that he needs to use. The query supports arguments that you can use to get specific data.

The anatomy of a GraphQL query

Mutations

In REST, any request can cause one modification and by convention, we don't use GET to do this. In GraphQL, you can somehow manipulate the query to modify the data on the server side, however, it's better to create a mutation to do this.

Here's one example of a GraphQL mutation:

mutation CreateReviewForEpisode($ep: Episode!, $review: ReviewInput!) {
createReview(episode: $ep, review: $review) {
stars
commentary
}
}
{
"ep": "JEDI",
"review": {
"stars": 5,
"commentary": "This is a great movie!"
}
}

As you can see the structure of one mutation is very similar to queries. But, now we have some variables represented by the dollar sign $ep, $review

While query fields are executed in parallel, mutation fields run in series, one after the other. (Learn more about this here)

In simple terms, Queries will fetch the data, Mutations will modify the data either to create, update, or delete.

Subscriptions

As queries, subscriptions enable you to fetch data, however, they create a more constant connection with your server allowing the server to notify the client whenever one event happens.

Subscriptions are useful for notifying your client in real-time about changes to back-end data, such as the creation of a new object or updates to an important field.

Is recommended to use subscriptions in cases where you need to make small changes in large objects because is expensive to query big objects just to change a small part of them, using subscriptions you can fetch the object and the server will take care of just updating the necessary fields.

Another case scenario, also described in the documentation, is one message app where the user needs to receive the message as soon as available.

When you add your comment on this post I will probably receive one notification created by one GraphQL Subscription!

Here's a quick example of a subscription definition.

Server-Side

You define the subscription as a field of your type on the schema.

type Subscription {
commentAdded(postID: ID!): Comment
}

So, the commentAdded subscription will notify the client whenever the post receives a new update. In that case, we are receiving the postID as a parameter.

Client-side

For the client side, I will use JS just to demonstrate, but you can use whatever language you decide to.

const COMMENTS_SUBSCRIPTION = gql`
subscription OnCommentAdded($postID: ID!) {
commentAdded(postID: $postID) {
id
content
}
}
`;

After that, when your server receives new data for the post that your client is listening to, you will be notified with the data that you asked for on the query, in that case: id and content.

In general, Subscriptions use WebSockets to handle the data flow. You can still have the traditional HTTP POST for Queries and Mutations, but for the subscription, you can opt to use WebSockets (Learn more about this here).

What is the best?

It really depends on your product and the resources available, in my opinion, I like to use GraphQL when the server needs to retrieve data for mobile and web applications using the same API. Or when I’m working with Microservices.

But I also like to work with REST when the application is simple or it is one system that already exists but I need to create something to make it available to other services.

WebSockets on the other hand, sounds more like a tool for a feature, in most cases, you can use it for Push Notifications, Messaging Apps, Real-Time Applications, and Live data streaming.

As a developer, your mission is to find the best solution with the tools you have, and I hope that you have learned at least one new approach by reading this post!

I really like to read the comments feel free to express yourself! See you soon!!

References:

--

--