Using Redis for Caching (2023)
Tags: javascript, react, go, programming
Published: 2022-10-20 06:29:20

*In case it helped :)*
<a href="https://www.buymeacoffee.com/aseemwangoo" target="_blank"><img src="https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png" alt="Pass Me A Coffee!!" style="height: 41px !important;width: 174px !important;box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;" ></a>

<!-- wp:paragraph -->
<p>We will cover briefly:</p>
<!-- /wp:paragraph -->

<!-- wp:list {"ordered":true} -->
<ol><li>Caching APIs (Go) using Redis</li><li>Redis Subscription using Pub/Sub</li><li>Calling API using React</li></ol>
<!-- /wp:list -->

{% youtube pgh4DicuixA %}

<!-- wp:heading {"level":3} -->
<h3>What is&nbsp;Redis?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Redis, which stands for <strong>Re</strong>mote <strong>Di</strong>ctionary <strong>S</strong>erver, is a fast, open source, in-memory, key-value data store. It delivers sub-millisecond response times, enabling millions of requests per second for real-time applications.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Redis is a key-value-based <a href="https://databasecamp.de/en/data/nosql-databases" rel="noreferrer noopener" target="_blank">NoSQL</a> database that stores data in memory, i.e. in RAM.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><strong>Use cases of Redis</strong></p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul><li>Caching</li><li>Geospatial</li><li>Chat, messaging, and queues</li><li>Gaming leaderboards</li></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p><strong>Advantages of Redis</strong></p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul><li>Simple, fast, and easy to use</li><li>Supports a variety <a href="https://redis.io/docs/data-types/tutorial/" rel="noreferrer noopener" target="_blank">of data structures</a></li><li>Allows storing key and value pairs as large as <code>512 MB</code>&nbsp;</li><li>High availability using <a href="https://redis.io/topics/sentinel" rel="noreferrer noopener" target="_blank">Redis Sentinel</a></li></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p><strong>Disadvantages of Redis</strong></p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul><li>Requires huge RAM (although depends on the type of application)</li><li>Failover happens if the master at least <code>1</code> slave</li><li>Data can only be accessed via keys</li></ul>
<!-- /wp:list -->

<!-- wp:heading {"level":4} -->
<h4>Setting up&nbsp;Redis&nbsp;</h4>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>We will setup <a href="https://redis.io/download/" target="_blank" rel="noreferrer noopener">Redis</a> using <a href="https://hub.docker.com/_/redis/" target="_blank" rel="noreferrer noopener">Docker</a></p>
<!-- /wp:paragraph -->

```yaml
docker run -d -p 6379:6379 --name redis redis
```

<!-- wp:paragraph -->
<p>Nowadays there are some hosting providers such as <a href="https://aws.amazon.com/redis/" target="_blank" rel="noreferrer noopener">AWS</a>, <a href="https://redislabs.com/" target="_blank" rel="noreferrer noopener">Redis Labs</a>, or <a href="https://upstash.com/?utm_source=goredis" target="_blank" rel="noreferrer noopener">Upstash</a> that provide Redis on the cloud.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>There are many ways of connecting to <a href="https://redis.io/docs/clients/" rel="noreferrer noopener" target="_blank">Redis</a>. In our case, we will be using the <code><a href="https://redis.io/topics/rediscli" rel="noreferrer noopener" target="_blank">RedisCLI</a></code> Since we have the docker setup ready, let's connect.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Here is an example of using the <code>RedisCLI</code> tool to set, get and delete a value from the Redis</p>
<!-- /wp:paragraph -->

```yaml
% docker exec -it redis redis-cli
127.0.0.1:6379> set key value
OK
127.0.0.1:6379> get key
"value"
127.0.0.1:6379> del key
(integer) 1
127.0.0.1:6379>
```

<!-- wp:paragraph -->
<p>Some other useful commands</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><code>keys</code> *: for finding all the keys</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><code>FLUSHALL</code>&nbsp;: delete all keys from all databases.<br><code>FLUSHDB</code>&nbsp;: delete all keys from the currently selected DB.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><code>EXPIRE</code> key 120: key will be deleted in <code>120</code>seconds</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3>Caching APIs (Go) using&nbsp;Redis</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>There are multiple clients available in <a href="https://redis.io/docs/clients/#go" rel="noreferrer noopener" target="_blank"><strong>Go</strong></a> for implementing Redis. However, in this article, we will be using <code><a href="https://github.com/go-redis/redis" rel="noreferrer noopener" target="_blank">Go-redis</a></code></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><strong>Go-Redis</strong></p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul><li>Go-Redis is a type-safe, Redis client library for Go.&nbsp;</li><li>It is a Redis client able to support a Redis cluster and is designed to store and update slot info automatically with a cluster change.</li><li>It supports features like <code><a href="https://redis.uptrace.dev/guide/go-redis-pubsub.html" rel="noreferrer noopener" target="_blank">Pub/Sub</a></code> <code><a href="https://redis.uptrace.dev/guide/go-redis-sentinel.html" rel="noreferrer noopener" target="_blank">Sentinel</a></code>, and pipelining</li></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p><strong>Create APIs using Gorilla Mux</strong></p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul><li>We will be using <a href="https://github.com/gorilla/mux" rel="noreferrer noopener" target="_blank">Gorilla Mux</a> to create the APIs locally</li><li>It implements a request router and dispatcher to match the incoming requests.</li></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p>Install it using</p>
<!-- /wp:paragraph -->

```go
go get -u github.com/gorilla/mux
```
<!-- wp:list -->
<ul><li>We will register the following endpoints:</li></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p><code>GET /users/:id</code> — to get a user’s information based on the id. Sample response</p>
<!-- /wp:paragraph -->

```json
[
   {
      "id":"116c24b1-9425-4fe4-aec2-86ba7384733e",
      "name":"Bob",
      "age":29,     
      "source":""
   },
   {
      "id":"a3fa13d4-67a9-4ae6-9713-dce7043844d7",
      "name":"Alice",
      "age":29,
      "source":""
   }
]
```

GET /users — returns the users present in the database. Sample response 

```json
{
   "id":"116c24b1-9425-4fe4-aec2-86ba7384733e",
   "name":"Bob",
   "age":29,
   "source":""
}
```
<!-- wp:list -->
<ul><li>Next, we create the router instance using the <code>mux.NewRouter()</code> and assign the above-created routes to the respective handlers</li><li>Each of the corresponding handlers is passed ResponseWriter and Request as parameters, which help in returning the desired response to the client.</li><li>We then specify the server details using <code>http.Server</code> for running the HTTP server</li></ul>
<!-- /wp:list -->

```go
srv := &http.Server{
 Handler:      router,
 Addr:         ":8081",
 WriteTimeout: 15 * time.Second,
 ReadTimeout:  15 * time.Second,
}
log.Fatal(srv.ListenAndServe())
```

<!-- wp:paragraph -->
<p><code>Handler</code> : This is the object that responds to the incoming HTTP requests (which we created above)</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><code>Addr</code>&nbsp;: This specifies the TCP address for the server to listen on, which by default is <code>80</code>&nbsp;</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><code>WriteTimeout</code>&nbsp;: Maximum duration before timing out the writes of the response</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><code>ReadTimeout</code>&nbsp;: Maximum duration for reading the entire incoming request</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul><li>Finally, we run the server using <code>ListenAndServe</code> which listens on the network address specified in the <code>Addr</code> and serves the requests based on the <code>Handler</code>&nbsp;</li></ul>
<!-- /wp:list -->

<!-- wp:heading {"level":4} -->
<h4>Setting up&nbsp;Postgres</h4>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>We will be using Postgres for our database. Install it using docker with the following</p>
<!-- /wp:paragraph -->

```yaml
docker run \
  -d \                                     
  -e POSTGRES_HOST_AUTH_METHOD=trust \
  -e POSTGRES_USER=user \
  -e POSTGRES_PASSWORD=password \
  -e POSTGRES_DB=dbname \
  -p 5432:5432 \
  postgres
```

<!-- wp:list -->
<ul><li>Verify if the new container is created and running at 0.0.0.0:5432<br><code>docker ps -a</code> For managing the database from the browser, install <a href="https://www.pgadmin.org/download/" target="_blank" rel="noreferrer noopener">pgAdmin</a> and connect to it using the above credentials, if all is good, you should see</li></ul>
<!-- /wp:list -->

<!-- wp:image {"align":"center"} -->
<figure class="wp-block-image aligncenter"><img src="https://cdn-images-1.medium.com/max/800/1*CazxSZgKc64-lbsmCw5C0Q.png" alt="Postgres database"/><figcaption>Postgres database</figcaption></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>We will create a table called <code>users</code> which will have the following schema</p>
<!-- /wp:paragraph -->

<!-- wp:image {"align":"center"} -->
<figure class="wp-block-image aligncenter"><img src="https://cdn-images-1.medium.com/max/800/1*Sx3U9aMu4V2wtT2vFoCVtQ.png" alt="Users table "/><figcaption>Users table&nbsp;</figcaption></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>Let’s insert some dummy data using </p>
<!-- /wp:paragraph -->

```sql
INSERT INTO public.users(
 id, created_time, name, updated_time, age)
 VALUES (uuid_generate_v4(), NOW(), 'alice', NOW(), 29);
// IN CASE ANY ERROR RUN THIS
CREATE EXTENSION IF NOT EXISTS "uuid-ossp"
```

<!-- wp:paragraph -->
<p>For connecting to Postgres using <code>Go</code> we will install <a href="github.com/jackc/pgx/v4" target="_blank" rel="noreferrer noopener">this</a> Here is the snippet</p>
<!-- /wp:paragraph -->

```go
host := "127.0.0.1"
port := "5432"
user := "user"
password := "password"
dbname := "dbname"
psqlInfo := fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=disable", host, port, user, password, dbname)
result, err := sql.Open("postgres", psqlInfo)
if err != nil {  
   log.Fatalf("Error in connection : %s", err)
}
```
<!-- wp:paragraph -->
<p>Here is the struct for the <code>users</code>&nbsp;</p>
<!-- /wp:paragraph -->

```go
type Users struct {
 ID          uuid.UUID `json:"id"`
 Name        string    `json:"name"`
 Age         int       `json:"age"`
 CreatedTime string    `json:"created_time"`
 UpdatedTime string    `json:"updated_time"`
 Source      string    `json:"source"`
}
```
<!-- wp:paragraph -->
<p>API and get users by id API are created, we will use the Gorilla Mux to create a <code>localhost</code> server and listen to the endpoints</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":4} -->
<h4>Caching APIs</h4>
<!-- /wp:heading -->

<!-- wp:image {"align":"center","ampLightbox":true} -->
<figure class="wp-block-image aligncenter"><img src="https://cdn-images-1.medium.com/max/800/1*jI76sdMEWFSYzPI4bt_Ftg.png" alt="Redis between DB and client"/><figcaption>Redis between DB and&nbsp;client</figcaption></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>For connecting to the <code>Redis</code> we create a Redis Client using <code><a href="https://github.com/go-redis/redis/blob/v8.11.5/redis.go#L546" target="_blank" rel="noreferrer noopener">NewClient</a></code> We specify the address at which the Redis exists</p>
<!-- /wp:paragraph -->

```go
client := redis.NewClient(&redis.Options{
 Addr:        "127.0.0.1:6379",
 DB:          0,
 DialTimeout: 100 * time.Millisecond,
 ReadTimeout: 100 * time.Millisecond,
})
```

<!-- wp:list -->
<ul><li>The configuration options are available through the <code>redis.Options</code> parameter.</li></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p><code>Addr</code>&nbsp;: String of host and the port address, since we are hosting Redis locally, the value is <code>127.0.0.1</code> and by default, Redis runs on the port <code>6379</code>&nbsp;</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><code>DB</code>&nbsp;: The database which will the selected after connecting to the server. By choosing <code>0</code> we mean to use the default database.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><code>DialTimeout</code>&nbsp;: In case our connection to the Redis server gets broken, we specify the timeout for establishing the new connection</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><code>ReadTimeout</code>&nbsp;: This allows putting a timeout for the socket reads. In case any of the Redis server requests reach this timeout, the command calling it will fail instead of blocking the server.</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul><li>To check if we connected to the server, we call <code><a href="https://pkg.go.dev/github.com/go-redis/redis/v8#Client.Ping" target="_blank" rel="noreferrer noopener">Ping</a></code> using the client we created above. If there is no error, that implies we are connected to the Redis server.</li><li>Finally, we return the Redis client which internally may have zero or more connections.</li></ul>
<!-- /wp:list -->

```go
if _, err := client.Ping().Result(); err != nil {
 return nil, err
}
return &Client{
 client: client,
}, nil
```

<!-- wp:paragraph -->
<p><strong>Get and Set Keys</strong></p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul><li>The use case we would be following is whenever the front end asks for the details of a particular user, we would fetch it from the API and then cache it. </li><li>Subsequent requests for the particular user would be served from the cache until the cache key expires (which we set to <code>20 seconds</code> )</li><li>We will be making use of <code><a href="https://github.com/go-redis/redis/blob/v8.11.5/commands.go#L890" target="_blank" rel="noreferrer noopener">Set</a></code> to set the value in the cache</li></ul>
<!-- /wp:list -->

```go
func (c *Client) SetUser(key string, user structs.Users) {
 json, err := json.Marshal(user)
 if err != nil {
  log.Fatal(err)
 }
 c.client.Set(key, json, 20*time.Second)
}
```

<!-- wp:quote -->
<blockquote class="wp-block-quote"><p>Note: Here we are taking the <code>user</code>struct as input. We are then converting the Go struct into JSON (aka marshaling) since JSON is a language-independent data format.</p></blockquote>
<!-- /wp:quote -->

<!-- wp:list -->
<ul><li>We are setting the key pair with an optional expiration parameter of <code>20 seconds</code> This means the key will automatically expire in the given duration.</li><li>In case there is no expiration parameter, it means <code>Zero expiration</code> meaning the key has no expiration time.</li></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p><strong>Get keys</strong></p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul><li>We will be making use of <code><a href="https://github.com/go-redis/redis/blob/v8.11.5/commands.go#L784" target="_blank" rel="noreferrer noopener">Get</a></code> for retrieving the value of the key</li></ul>
<!-- /wp:list -->

```go
func (c *Client) GetUser(key string) (user *structs.Users) {
 val, err := c.client.Get(key).Result()
 resp := structs.Users{}
 err = json.Unmarshal([]byte(val), &resp)
 return &resp
}
```

<!-- wp:list -->
<ul><li>The response is in the form of a string and then we convert the byte data into the original <code>user</code> struct (aka unmarshalling)</li><li>Inside this function, we additionally add a Redis publisher (which we will see in the next section).</li></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p><strong>Calling APIs</strong></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>We have this API endpoint hosted locally <code>GET /users/:id</code> — to get a user’s information based on the id.</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul><li>Once the client calls this endpoint, we first check in case the value for this request can be served from the cache.</li></ul>
<!-- /wp:list -->

<!-- wp:quote -->
<blockquote class="wp-block-quote"><p>Note: In case the data exists inside the cache, we set the <code>source: "cache"</code></p></blockquote>
<!-- /wp:quote -->

<!-- wp:list -->
<ul><li>Logically, the first request will always hit the server, hence the time taken for getting the response will be more.</li></ul>
<!-- /wp:list -->

<!-- wp:quote -->
<blockquote class="wp-block-quote"><p>Note: For getting the value from the server, we set the <code><em>source: "API"</em></code></p></blockquote>
<!-- /wp:quote -->

```go
router.HandleFunc("/users/{id}", func(w http.ResponseWriter, r *http.Request) {
 id := mux.Vars(r)["id"]
 val := redis.GetUser(id)
 if val != nil {
  val.Source = "cache"
  renderJSON(w, &val, http.StatusOK)
  return
 }
 user, err := GetUserByID(id)
 if err != nil {
  renderJSON(w, &user, http.StatusOK)
  return
 }
 redis.SetUser(id, user)
 user.Source = "API"
 renderJSON(w, &user, http.StatusOK)
})
```

<!-- wp:list -->
<ul><li>As we can see in the above snippet, we first invoke <code>redis.GetUser</code> to check the cache.</li><li>This function checks for the id inside the cache, if the id is present, it returns the value.</li><li>If the result fails, the function returns null and we proceed to invoke the API <code>GetUserByID</code> which hits our Postgres database</li></ul>
<!-- /wp:list -->

```json
{
   "id":"116c24b1-9425-4fe4-aec2-86ba7384733e",
   "name":"Bob",
   "age":29,
   "source":"API"
}
```

<!-- wp:paragraph -->
<p>s how it looks when the key is not present in Redis</p>
<!-- /wp:paragraph -->

<!-- wp:image {"align":"center"} -->
<figure class="wp-block-image aligncenter"><img src="https://cdn-images-1.medium.com/max/800/1*ST5YLQ6W1fmUkL52fBeiMQ.png" alt="Key not present in Redis"/><figcaption>Key not present in&nbsp;Redis</figcaption></figure>
<!-- /wp:image -->

<!-- wp:list -->
<ul><li>The result from the API is then cached in Redis, so the subsequent requests are now served by the cache (until <code>20 seconds</code> which is the key expiration duration)</li></ul>
<!-- /wp:list -->

```json
{
   "id":"116c24b1-9425-4fe4-aec2-86ba7384733e",
   "name":"Bob",
   "age":29,
   "source":"cache"
}
```

<!-- wp:paragraph -->
<p>This is how it looks when the key is present in Redis</p>
<!-- /wp:paragraph -->

<!-- wp:image -->
<figure class="wp-block-image"><img src="https://cdn-images-1.medium.com/max/800/1*X6MOmVp3Y1CFqgjKCUSMCw.png" alt=""/><figcaption>Key present in&nbsp;Redis</figcaption></figure>
<!-- /wp:image -->

<!-- wp:separator -->
<hr class="wp-block-separator has-alpha-channel-opacity"/>
<!-- /wp:separator -->

<!-- wp:heading {"level":4} -->
<h4>Redis Subscription using&nbsp;Pub/Sub</h4>
<!-- /wp:heading -->

<!-- wp:list -->
<ul><li>In the field of software engineering, publish-subscribe is a pattern where senders (publishers) categorize the messages into channels without knowing if there may be any subscribers.</li><li>On the other hand, subscribers show interest in one or more channels and only receive messages that are of interest, without knowing if there may be any publishers.</li><li>This decoupling of publishers and subscribers enhances greater scalability.</li></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p><strong>Redis Pub/Sub</strong></p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul><li>We will be using Redis for pub/sub, however, there are various other alternatives like Apache Kafka, Google cloud Pub/Sub, etc</li><li>In order to subscribe to channels, for instance, <code>foo</code> and <code>bar</code> the client uses <code><a href="https://redis.io/commands/subscribe" target="_blank" rel="noreferrer noopener">SUBSCRIBE</a></code> providing the names of the channels:</li></ul>
<!-- /wp:list -->

```yaml
SUBSCRIBE foo bar
```

<!-- wp:paragraph -->
<p>Messages sent by other clients to these channels will be pushed by Redis to all the subscribed clients.</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul><li>Once we have a Redis client subscribing to a channel, that client can no longer execute any other operations except unsubscribing from the current channel or subscribing to more channels.</li></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p><strong>Go-Redis Publisher</strong></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><code>Go-redis</code> allows to publish messages and subscribe to channels. It also automatically re-connects to Redis Server when there is a network error.</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul><li>Inside our get user function, we will create a publisher, using <code><a href="https://github.com/go-redis/redis/blob/v8.11.5/commands.go#L3172" target="_blank" rel="noreferrer noopener">redis.Publish(</a>)</code>. This function takes two arguments, the name of the <strong>channel</strong> to which we want to send the message and the <strong>message</strong>.</li><li>In our case, we set the channel name to <code>send-user-name</code> and the payload is the response from <code>redis.GetUser</code> (see above)</li><li>We are sending the marshaled payload to the channel using <code>Publish</code> This is because it allows transferring the data as <code>[]byte</code> </li><li>Since we are using a User struct, it can be encoded into a <code>[]byte</code> </li></ul>
<!-- /wp:list -->

```go
// Sample payload we are sending using pub/sub
{
   "id":"116c24b1-9425-4fe4-aec2-86ba7384733e",
   "name":"Bob",
   "age":29,
   "source":"cache"
}
// Publish using Redis PubSub
payload, err := json.Marshal(resp)
if err := c.client.Publish("send-user-name", payload).Err(); err != nil {
 log.Fatal(err)
}
```
<!-- wp:paragraph -->
<p><strong>Go-Redis Subscriber</strong></p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul><li>We create a subscriber using the <code><a href="https://github.com/go-redis/redis/blob/v8.11.5/redis.go#L686" target="_blank" rel="noreferrer noopener">redis.Subscribe()</a></code> function. </li><li>We will have one argument, the <strong>channel</strong> we want to subscribe to, which in our case is <code>send-user-name</code>.</li><li>Subscribe subscribes to the client to the specified channels. Since this method does not wait on a response from Redis, so the subscription may not be active immediately.</li><li>We create a new file that connects to the same Redis instance and calls the following</li></ul>
<!-- /wp:list -->

```go
topic := redisClient.Subscribe("send-user-name")
channel := topic.Channel()
for msg := range channel {
 u := &User{}
 // Unmarshal the data into the user
 err := u.UnmarshalBinary([]byte(msg.Payload))
 if err != nil {
  panic(err)
 }
fmt.Printf("User: %v having age: %v and id: %v\n", u.Name, u.Age, u.ID)
 log.Println("Received message from " + msg.Channel + " channel.")
}
```

<!-- wp:list -->
<ul><li>The result of the <code>subscribe</code> is a <code>PubSub</code> and we extract the channel property out of this object</li><li>This Channel returns a Go channel for concurrently receiving messages. If the channel is full for 30 seconds the message is dropped.</li><li>We loop over the channel and extract the data from it, which is of the type <code>Message</code> Each message object comprises of</li></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p><code>Channel</code>&nbsp;: This is the channel name</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><code>Payload</code>&nbsp;: The marshaled data received in the channel</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><code>Pattern</code>&nbsp;: Pattern for the message</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul><li>The data received inside the message can be fetched using <code>msg.Payload</code> Since its marshaled, we will unmarshal it using the <code>UnmarshalBinary</code> and transform back into <code>User</code> struct.</li><li>Finally, we can access the struct properties and print inside the console. We also print the message’s channel name, just for fun!!</li></ul>
<!-- /wp:list -->

<!-- wp:image {"align":"center"} -->
<figure class="wp-block-image aligncenter"><img src="https://cdn-images-1.medium.com/max/800/1*lTOAAsbWv6_FAvcXgBuJMA.png" alt="Redis subscriber"/><figcaption>Redis subscriber</figcaption></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>Here, we get the message channel name <code>send-user-name</code> and the user details for <code>Bob</code>&nbsp;</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":4} -->
<h4>Calling API using&nbsp;React</h4>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>In the above section, we created and hosted the APIs locally using <a href="https://github.com/gorilla/mux" rel="noreferrer noopener" target="_blank">Gorilla Mux</a>. We will now consume these APIs from the front end using React</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>We will be using Axios for calling the APIs. Let’s install this dependency. </p>
<!-- /wp:paragraph -->

```javascript
npm install axios
```

<!-- wp:list -->
<ul><li>Axios is a lightweight HTTP client which makes calling requests very intuitive. It is similar to the JavaScript <code>Fetch API</code> </li><li>It works well with JSON data and does the heavy lifting of setting the request headers.</li><li>It has better error handling for accessing the response and integrates well with async-await syntax.</li><li>It can be used on the server as well as the client.</li></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p><strong>Integrate into React</strong></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>We will be using the hooks <code>useEffect</code> and <code>useState</code> A <code>hook</code>is a special function that lets you “hook into” React features.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><strong>useEffect</strong></p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul><li>Using this Hook, we instruct React that our components need to do something after rendering. By default, <code>useEffect</code> runs after each render of the component where it’s called.</li><li>A common use of this hook is to fetch data and display it.</li><li>React remembers the function you passed, and invokes it later after the DOM updates.</li></ul>
<!-- /wp:list -->

<!-- wp:quote -->
<blockquote class="wp-block-quote"><p>Note: We have an empty array at the end of the useEffect Hook for making sure the internal function inside renders only once.</p></blockquote>
<!-- /wp:quote -->

<!-- wp:list -->
<ul><li>If we want our effects to run less often, we provide the second argument (which is an array of values). These can be considered as the dependencies for the effect and if any changes (since the last time), the effect runs again.</li></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p><strong>useState</strong></p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul><li>It is a way of adding a state to the components and <code>preserve</code>some values between the function call. </li><li>In general, variables “disappear” when the function exits but state variables are preserved by React.</li><li>This state can be an array, object, number, boolean, etc.</li><li>The argument passed to the <code>useState()</code> is the initial state. </li></ul>
<!-- /wp:list -->

```javascript
const [fetchedData, setFetchedData] = useState([]);
useEffect(() => {
  const getData = async () => {
      const data = await axios.get(
          "http://localhost:8081/users"
      );
      setFetchedData(data);
  };
  getData();
}, []);
```

<!-- wp:list -->
<ul><li>To make a <code>GET</code> request using Axios we use the&nbsp;<code>.get()</code> method. The response is returned as an object.</li><li>We use the&nbsp;<code>.data</code> property from the response to get the requested data and set it inside the hook using the <code>setFetchedData</code>&nbsp;</li></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p><strong>Request responses:</strong></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>When the page loads for the first time, the API hits our backend. The result <code>fetchedData</code> is then displayed on the page.&nbsp;</p>
<!-- /wp:paragraph -->

<!-- wp:quote -->
<blockquote class="wp-block-quote"><p>Notice, source: API&nbsp;</p></blockquote>
<!-- /wp:quote -->

<!-- wp:image {"align":"center"} -->
<figure class="wp-block-image aligncenter"><img src="https://cdn-images-1.medium.com/max/800/1*SlPKGGzgF8GVq0ZoCdEcNg.png" alt="Source: API"/><figcaption>Source: API</figcaption></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>And on the next request, the API hits our cache, displayed with <code>source:cache</code></p>
<!-- /wp:paragraph -->

<!-- wp:image {"align":"center"} -->
<figure class="wp-block-image aligncenter"><img src="https://cdn-images-1.medium.com/max/800/1*mY3AfhgxZeApZ3VAUwmc1w.png" alt="Source: Cache"/><figcaption>Source: Cache</figcaption></figure>
<!-- /wp:image -->

{% youtube pgh4DicuixA %}

<!-- wp:paragraph -->
<p><a rel="noreferrer noopener" href="https://github.com/AseemWangoo/golang-programs" target="_blank"><em>Source code for Go</em></a>

<!-- wp:paragraph -->
<p><a rel="noreferrer noopener" href="https://github.com/AseemWangoo/expriments_with_react" target="_blank"><em>Source code for React</em></a>


*In case it helped :)*
<a href="https://www.buymeacoffee.com/aseemwangoo" target="_blank"><img src="https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png" alt="Pass Me A Coffee!!" style="height: 41px !important;width: 174px !important;box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;" ></a>