-
Notifications
You must be signed in to change notification settings - Fork 0
4. Chaining
In order to start using chaining, we need to implement the SpringramUserDetailsService
interface. This interface is responsible for providing data about the current user chain to the library.
Let's write a simple implementation class that will use some kind of repository and return the SpringramUserDetails
implementation.
@Service
public class MyUserDetailsService implements SpringramUserDetailsService {
private final UserRepository repository;
public MyUserDetailsService(UserRepository repository) {
this.repository = repository;
}
@Nullable
@Override
public SpringramUserDetails loadById(long id) {
final User byId = repository.getById(id);
return byId == null ? null : new MySpringramUserDetails(byId);
}
record MySpringramUserDetails(User user) implements SpringramUserDetails {
@Nullable
@Override
public String getChain() {
return user.getChain();
}
}
}
Now we need to set our service in the configuration, below is an example of how to do this.
@Configuration
public class MySpringramConfigurer implements SpringramConfigurer {
private final SpringramUserDetailsService userDetailsService;
public MySpringramConfigurer(SpringramUserDetailsService userDetailsService) {
this.userDetailsService = userDetailsService;
}
@Override
public void configurePathMatcher(PathMatchingConfigurer configurer) {
configurer.setUserDetailsService(userDetailsService);
}
}
Now, using the @Chain
annotation, we can specify which chain the handler method belongs to.
@BotController
public class SayController {
private static final String MESSAGE_INPUT_CHAIN = "say/message-input";
private final UserService userService;
public SayController(UserService userService) {
this.userService = userService;
}
@CommandMapping("say")
public SendMessage say(ChatTextMessage message) {
final User user = userService.getUser(message.getFromUser().getId());
user.setChain(MESSAGE_INPUT_CHAIN);
userService.saveUser(user);
return SendMessage.builder()
.chatId(String.valueOf(message.getChatId()))
.text("Send message now")
.build();
}
@CommandMapping
@Chain(MESSAGE_INPUT_CHAIN)
public SendMessage sayInput(ChatTextMessage message) {
final User user = userService.getUser(message.getFromUser().getId());
user.setChain(null);
userService.saveUser(user);
return SendMessage.builder()
.chatId(String.valueOf(message.getChatId()))
.text("Awesome! You typed: " + message.getText())
.build();
}
}
Since we are storing the chain data in our user, we simply set the value with a setter and then save it to the database.
As you can see, the library does not store any state. It is up to you as the developer to determine where the state will be stored and how you will update it. This approach allows you to write more productive and understandable code, and the library eliminates unnecessary complexity.