A simple leaderboard app in Spring boot using redis

 Sure! I'll walk you through setting up a simple Spring Boot project where Redis is used to maintain a leaderboard.

Steps:

  1. Set up Spring Boot Project: We'll use Spring Initializr to create a simple Spring Boot application.
  2. Add Dependencies: We will need Redis dependencies.
  3. Configure Redis: We'll configure the Redis connection settings.
  4. Create Service for Leaderboard: We will implement logic to update and retrieve leaderboard data.
  5. Create REST Endpoints: Expose REST endpoints to interact with the leaderboard.

1. Setting Up the Spring Boot Project

Go to Spring Initializr and create a new project with the following options:

  • Project: Maven Project
  • Language: Java
  • Spring Boot Version: Latest (2.7.x or 3.x)
  • Dependencies:
    • Spring Web
    • Spring Data Redis
    • Spring Boot DevTools (optional for development)

Download the zip file and unzip it.

2. Add Redis Dependencies

If you're using Maven, you need to add the Redis dependency to the pom.xml:

<dependencies>
    <!-- Spring Web Dependency -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- Redis Dependency -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>

    <!-- Redis Jedis client (or Lettuce) -->
    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
    </dependency>
</dependencies>

3. Configure Redis Connection

In your application.properties (or application.yml), configure the Redis connection:

spring.redis.host=localhost
spring.redis.port=6379
spring.redis.password=yourpassword (optional)
spring.redis.ssl=false

Make sure Redis is running locally. If it's not installed, you can download and start Redis from redis.io.

4. Create the Leaderboard Service

In the service class, we'll use Redis to store scores of users and retrieve them to create a leaderboard.

package com.example.leaderboard.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;

import java.util.Set;

@Service
public class LeaderboardService {

    private static final String LEADERBOARD_KEY = "leaderboard";

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    // Method to add/update user's score
    public void updateScore(String username, double score) {
        redisTemplate.opsForZSet().add(LEADERBOARD_KEY, username, score);
    }

    // Method to get the top N players
    public Set<ZSetOperations.TypedTuple<String>> getTopPlayers(int topN) {
        return redisTemplate.opsForZSet().reverseRangeWithScores(LEADERBOARD_KEY, 0, topN - 1);
    }

    // Method to get a player's rank
    public Long getPlayerRank(String username) {
        return redisTemplate.opsForZSet().rank(LEADERBOARD_KEY, username);
    }

    // Method to get a player's score
    public Double getPlayerScore(String username) {
        return redisTemplate.opsForZSet().score(LEADERBOARD_KEY, username);
    }
}

5. Create the REST Controller

Now, create a controller to expose REST endpoints that will interact with the LeaderboardService.

package com.example.leaderboard.controller;

import com.example.leaderboard.service.LeaderboardService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Set;
import org.springframework.data.redis.core.ZSetOperations;

@RestController
@RequestMapping("/leaderboard")
public class LeaderboardController {

    @Autowired
    private LeaderboardService leaderboardService;

    // Endpoint to update user's score
    @PostMapping("/update")
    public String updateScore(@RequestParam String username, @RequestParam double score) {
        leaderboardService.updateScore(username, score);
        return "Score updated successfully!";
    }

    // Endpoint to get the top N players
    @GetMapping("/top/{n}")
    public Set<ZSetOperations.TypedTuple<String>> getTopPlayers(@PathVariable int n) {
        return leaderboardService.getTopPlayers(n);
    }

    // Endpoint to get a player's rank
    @GetMapping("/rank/{username}")
    public Long getPlayerRank(@PathVariable String username) {
        return leaderboardService.getPlayerRank(username);
    }

    // Endpoint to get a player's score
    @GetMapping("/score/{username}")
    public Double getPlayerScore(@PathVariable String username) {
        return leaderboardService.getPlayerScore(username);
    }
}

6. Main Application Class

Make sure your SpringBootApplication class is set up properly to run the Spring Boot application.

package com.example.leaderboard;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class LeaderboardApplication {
    public static void main(String[] args) {
        SpringApplication.run(LeaderboardApplication.class, args);
    }
}

7. Running Redis Locally

If you haven't installed Redis locally, you can follow the instructions on redis.io/download. Once Redis is installed, run it on port 6379 (default). This can be done by running:

redis-server

8. Test the Application

Once everything is set up, you can run the Spring Boot application using:

mvn spring-boot:run

Now, you can test the following endpoints using Postman or CURL:

  • Update Score (POST request):

    POST http://localhost:8080/leaderboard/update?username=user1&score=100
    
  • Get Top N Players (GET request):

    GET http://localhost:8080/leaderboard/top/5
    
  • Get Player Rank (GET request):

    GET http://localhost:8080/leaderboard/rank/user1
    
  • Get Player Score (GET request):

    GET http://localhost:8080/leaderboard/score/user1
    

Conclusion

In this simple Spring Boot application, we:

  • Set up a leaderboard using Redis' ZSet data structure.
  • Implemented the functionality to update a user's score, get the top N players, retrieve a player's rank, and get their score.

Redis is great for managing leaderboards because of its efficient support for sorted sets (ZSet), making it fast for storing and retrieving scores in ranked order.

Comments

Popular posts from this blog

What is a REST controller & Write a simple REST controller in Spring boot 3.xx

DSA Practice: How to invert a binary tree

Senior Engineer Interview Prep Notes