avatarSuraj Mishra

Summary

This article provides a guide on creating a unique ID generator microservice using Spring Boot and Java UUID, with a focus on generating and checking unique identifiers.

Abstract

The article introduces the concept of building a unique ID generator microservice using Spring Boot. It outlines the process of setting up a Spring Boot project with the necessary dependencies, implementing a UUID-based controller to generate unique identifiers, and creating a logic class to handle the UUID generation. Additionally, it discusses the implementation of an endpoint to verify if a unique ID has been previously issued, using a simple HashSet-based cache for storage. The article acknowledges the limitations of the current approach, such as the lack of ordered IDs and the need for a more robust cache system suitable for multithreaded environments and long-term persistence. It suggests potential improvements, including the use of Redis or Memcache for caching and the possibility of scaling the application layer and cache system. The conclusion promises future articles that will address the outlined issues and enhance the microservice's robustness.

Opinions

  • The author believes that ordered IDs are generally preferable for ease of searching and association with values.
  • The article suggests that the current cache implementation is insufficient for production environments and requires enhancements for multithreading and persistence.
  • It is implied that the use of distributed and scalable databases is contingent on the specific use case, such as the need to retain IDs for retry mechanisms within a certain timeframe.
  • The author advocates for the scalability of the application layer by adding more instances and using distributed cache clusters like Redis/Memcache.
  • The article teases future content that will likely delve into more advanced and production-ready implementations of the unique ID generator microservice.

How to Make Unique ID Generator Microservice Using Spring Boot

Using UUID to generate a unique ID

Originally Published in https://asyncq.com/

Introduction

  • In this article, we will learn how we can use Spring boot and Java UUID class to generate a unique Identifier.
  • Keep in mind that this is a very basic implementation that just touches upon some concepts and builds on top of that.
  • In future articles, we will cover more interesting and production-level concepts and implementation around this topic.

Create Spring Boot Project

  • We can create a UUID-Generator project at start.spring.io.
  • We just need Spring Web and Devtools as a dependency.

Solution

  • We will use the UUID class which is available for us to generate a unique identifier.

Controller

  • Our controller consists of a GET endpoint that essentially returns the UUID to the rest client
package com.example.uuidgen.controller;

import com.example.uuidgen.logic.UUIDGeneratorLogic;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("uuid-generator")
public class UUIDController {

    @Autowired
    private UUIDGeneratorLogic uuidGeneratorLogic;

    @GetMapping("/new")
    private String getID(){
        return uuidGeneratorLogic.generateID();
    }
}

Logic

  • Logic class using Java UUID library to generate a unique identifier.
package com.example.uuidgen.logic;

import org.springframework.stereotype.Service;

import java.util.UUID;

@Service
public class UUIDGeneratorLogic {

    public String generateID(){
        return UUID.randomUUID().toString();
    }
}
  • Now, let's run the application and check if our endpoints are functioning as expected.

Postman Request

  • Now when we send a request we get the UUID as result.

Check If a Unique ID was Issued Before

  • We are also providing another endpoint to check if the given Unique ID was generated before, if yes then we return true and otherwise false.
  • Here we are keeping things simple and using HashSet to store any issued ID and use it to check if it was issued before.
  • If our Set contains the issued key then we return true otherwise we return false.

Rest Endpoint

  • We created another get endpoint “check” to check if the given id has already been issued before.
  • This endpoint expects the id will be passed as a parameter.
    @GetMapping("/check")
    private Boolean checkID(@RequestParam("id") String id){
        return uuidGeneratorLogic.checkID(id);
    }

Simple Cache Logic

  • Our cache is very naive that is essentially just a HashSet. We are storing the Issued ID into a set before returning it to the user.
  • And during the check request, we simply check if it exists in the cache.
package com.example.uuidgen.cache;

import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

@Service
public class Storage {

    // create global scope
    Set<String>  idSet = new HashSet<>();

    public Boolean put(String id){
        return idSet.add(id);
    }

    public Boolean contains(String id){
        return idSet.contains(id);
    }
}
package com.example.uuidgen.logic;

import com.example.uuidgen.cache.Storage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.UUID;

@Service
public class UUIDGeneratorLogic {

    @Autowired
    private Storage cache;

    public String generateID(){
        String id = UUID.randomUUID().toString();
        cache.put(id);
        return id;
    }

    public Boolean checkID(String id){
        return cache.contains(id);
    }

}
  • The logic method is just a simple Hashset check.
public Boolean checkID(String id){
        return cache.contains(id);
}

Testing

  • Then we pass it using the check endpoint and it returns true since this id is already generated.

Problems with the Current Approach

UUID Generation

  • In our current approach, we generate UUID which will provide a unique value every time generate/new endpoint is called. But these IDs are not in order. Generally, orderedId’s are good so that we can keep them sorted which helps with searching for the ID and getting associate value attached to the ID.

Storage

  • Another problem is with Cache, which is essentially just a Set. The first thing that we need to do is to make our cache usable in a multithreaded environment. We can use synchronized or some other strategies.
  • We can also use sophisticated caches like Redis or Memcache as separated and decoupled from our application.
  • We also need to persist our records in some distributed and scalable database so that we can store our IDs for as long term. This is not necessarily required, because in some cases we just need to check the issued id for duplication in a given amount of time. For example, consider a use case like checking if this request was made within 24 hours (generally due to the retry mechanism), in that case, we keep data in our cache for 24 hours or so and we never require that id again.

Scaling

  • We can scale the application layer by adding more instances. Since UUID is fairly enough to generate a unique id on every request.
  • For the cache system, we can use Redis/Memcache as distributed cluster and scale horizontally.

Conclusion

  • In this article, we cover a very basic implementation of a simple microservice that generates a unique id on each request.
  • We also added a check mechanism that checks for the given id already generated before.
  • In future articles, we will include all the issues mentioned in the Problems section and make our implementation more robust.

Before You Leave

Java
Uuid
Spring Boot
Programming
Coding
Recommended from ReadMedium