How to create LinkedIn-like reactions with Serverless Redis
Tags: webdev, javascript, tutorial, database
Published: 2021-05-19 11:12:31

---
title: How to create LinkedIn-like reactions with Serverless Redis
published: true
description: Production ready implementation of the LinkedIn-like reactions feature using Redis.
tags: webdev, javascript, tutorial, database
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/282n22kexnbz1qia86qa.jpg
---
As a side hustle, I teach tech recruiters web and software development technologies using plain English. It helps them with understanding job specs and resumes and it makes all of us, tech people, happier. 

I run a weekly newsletter and often get feedback from recruiters via email or LinkedIn DMs.

I thought that I could try to collect feedback using the “Reactions” feature just like LinkedIn or Facebook does. It’s not as informative as personalised messages but is a simple feature that may incentivize more people to provide some general feedback.

Either way, it’s worth trying and as a software developer, I can’t wait to implement it.

This tutorial is about implementing a feature that will be used in real life on my project. 

###Planning
As with any feature or project, we start with the planning phase.

I am going to stick with LinkedIn-like reactions because they are more appropriate for the type of content I post. 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bo72ffqe726lwm6oiuk5.png)

I will use the Like, Insightful and Curious reactions and will substitute them with 👍, 💡 and 🤔 emojis respectively.

My static website is built with Gatsby. I do not use a database but I need one to store reactions. I need to decide what database to use.

I deploy with Netlify and I use functions for backend related functionality. That means that I go serverless. Ideally, I need a serverless database too to not have to deal with deploying my own DB or overpaying for PaaS with fixed plans.

As of writing this article, I am using Netlify's free tier and can easily go for more features with a paid plan at a very good price. Using a reasonably priced database would be a perfect complement to my current tech stack.

These are the tasks:
##### 1. Research database options.
I need to find out what serverless databases exist and choose one.

##### 2. Create a Serverless Backend with functions for: 
* storing reactions and incrementing/decrementing the count
* fetching reactions by a post id

##### 3. Create the "reactions" component.
Gatsby is based on React and I will build a simple “reactions” component.

##### 4. Put it all together to make my static website a little bit dynamic.
Static websites can have dynamic features and it’s what makes them, static site generators so incredibly awesome. 

In this tutorial, I will focus on the first two tasks. The “reactions" component implementation you can check in the  [source code](https://github.com/sandorTuranszky/gatsby-starter-blog-with-LinkedIn-like-reactions/tree/main/src/components)

###Research
This second phase in Software Development Life Cycle (SDLC) is named Prototyping but I call it Research in this tutorial because I will skip the proof of concept (POC) part.

Research is always fun because it provides a great opportunity to learn about new technologies. While this process is interesting, it can also take a lot of time if we do not make our research more specific. 

SQL and NoSQL are the most common database types. The choice isn’t difficult if we know what data will be stored. Let’s quickly take a look at what data structure we will have.

Every **post has a set of reactions** and we need to **count** those **reactions**.

Since I simply want to get an idea about how people react to my posts, I will not require them to log in or limit the types of reactions. 

Based on the above, our data structure could look as follows for a post with 3 likes, 12 insightful and 7 curious reactions: `{ "like":3, "insightful":12, "curious":7 }`

A NoSQL database looks like a good choice for storing and manipulating a data structure like the above. 

I immediately thought of MongoDB and Redis. However, based on how we will manipulate data, namely persist it once and then increment or decrement certain values, I decide in favor of Redis.

The reason being is that Redis has built-in and performance-optimized commands to support what we need.

Besides that, I found a serverless Redis database [Upstash](https://upstash.com?utm_source=sndr_1) which looks simple and has reasonable pricing including a free plan. I like starting free and paying as I scale.

Note that we are using Redis as a **primary database**. Redis can be configured to write data to disk which provides a degree of [data safety](https://redis.io/topics/persistence) comparable to what PostgreSQL offers.

Redis solves a much wider range of problems than just in-memory caching and can be used either as a primary database or as an additional database for solving problems that other databases struggle with.

I like that Upstash [enables persistence](https://docs.upstash.com/overall/durability?utm_source=sndr_1) by default keeping data both in memory and disk. This removes the headache of configuring things which would be an overhead for a task like this one. This is why I always use serverless and PaaS whenever possible.

To sum up this part, let me share with you an interesting [free e-book](https://redislabs.com/ebook/redis-in-action/) called “Redis in Action” packed with valuable information and use-cases for Redis.

###Serverless Backend
I will use Netlify’s serverless functions with Node instead of creating my own backend. You are free to use any backend architecture. 

The easiest way to connect Redis with Upstash is to use the [redis-client](https://github.com/NodeRedis/node-redis) as described [here](https://docs.upstash.com/howto/connectwithtls?utm_source=sndr_1).

First things first, we need to create a Serverless Redis database following this [Getting Started guide](https://docs.upstash.com?utm_source=sndr_1).

Please, note that I leave out the [Strong Consistency Mode](https://docs.upstash.com/overall/consistency?utm_source=sndr_1), because Eventual Consistency is suitable for my task.

This is the schema for naming the keys: **post:{id}:{reaction}**
1. **post:{id}:like** -> `post:856f9d0a:like`
2. **post:{id}:insightful** -> `post:856f9d0a:insightful`
3. **post:{id}:curious** -> `post:856f9d0a:curious` 

We could go with the most basic kind of Redis value known as [Strings](https://redis.io/topics/data-types#strings). But we’ll go with [hashes](https://redis.io/topics/data-types#hashes) because we want to store objects as value and it is advisable to [use hashes when possible](https://redis.io/topics/memory-optimization).

This is how we do it for a given post ID:
- To increment a reaction by 1, for example, “Like”, we will use the [HINCRBY](https://redis.io/commands/hincrby) command. If the key does not exist, it will create the key and set its value to 0 before incrementing. If the key does exist, it will simply increment by the value we provide. It allows us to reuse this function both for creating and updating reactions.

`HINCRBY post:856f9d0a:reactions like 1`

Here is the [implementation](https://github.com/sandorTuranszky/gatsby-starter-blog-with-LinkedIn-like-reactions/blob/main/lambda/react.js)

If we had to decrement reactions for cases when a reaction is removed or changed, we would simply pass the value to be incremented by a negative number: -1

- To read reactions for a post ID we’ll use the [HGETALL](https://redis.io/commands/hgetall) command which returns key-value pairs:

`HGETALL post:856f9d0a:reactions` -> `// will return {"like":"3","insightful":"1","curious":"2"}`

Here is the [implementation](https://github.com/sandorTuranszky/gatsby-starter-blog-with-LinkedIn-like-reactions/blob/main/lambda/reactions.js)

With this approach, knowing the post ID, we can efficiently set, update and retrieve reactions for a post with a ridiculously small amount of code.

Post IDs are not short but we will use them for naming keys because they will not cause any noticeable memory usage increase in our case. 

But you should always keep in mind that along with having a readable key naming schema, you need to control the length of keys. Long keys can use more memory and even cause performance implications as described in the [Redis keys](https://redis.io/topics/data-types-intro#redis-keys) section.

###Off-topic
Even though this is not directly related to this tutorial, I know that later I will want to show the most popular posts based on reactions. 

To get posts with the most Likes, Insightful and Curious reactions, we need to track them using a [sorted set](https://redis.io/topics/data-types#sorted-sets).

For instance, this is how we store a post that received a Like reaction:
[ZINCRBY](https://redis.io/commands/zincrby) `reaction:like 1 post:856f9d0a`

And this is how we get the most liked 5 posts:
[ZREVRANGEBYSCORE](https://redis.io/commands/zrevrangebyscore) `reaction:like +INF -INF withscores LIMIT 0 5`

I will provide more details and a working implementation in one of my next posts.

It’s always a good idea to design a system taking into account all known future requirements and choose technologies that will support them in the future.

---

Here is a working implementation on my [website](https://techforitrecruiters.com/blog). Pick any [post](https://techforitrecruiters.com/blog/2021-05-02-what-is-a-content-management-system/) and you will find reactions at the bottom. The source code you can find [here](https://github.com/sandorTuranszky/gatsby-starter-blog-with-LinkedIn-like-reactions)

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e2j18fogq7ge56vjjouh.png)

###Conclusion
If you still perceive Redis as an in-memory cache, get ready because I have more posts coming up that cover powerful features backed by this amazing database. 

The next post will be about how I built a Q&A board for asking and upvoting the most interesting questions using Redis. 

Follow for more!