Implementing the outbox pattern in Spring

Mohammed Hewedy
3 min readFeb 28, 2023

--

Photo by Kristina Tripkovic on Unsplash

The Outbox Pattern is an old pattern, that usually has been used for years to solve similar problems that were introduced with Microservices.

It is when you need to save/update some information in the database and in the same “atomic” transaction want to communicate with some external service, such as a Message Queue.

Typical use case

In this case, you might choose to use 2PC, but It won’t work for you if you need to communicate with some external API instead of sending to a message queue or an external service.

Multiple solutions are available, among them is using the Outbox pattern by inserting the data you want to communicate with the other system in the database (hence we have a real atomic transaction, the first save/update and the second save), and then there’s another background process that picks the saved record and tries to send it for you.

Applying the outbox pattern

In this article, I will showcase a simple Java/Spring library that does this automatically using AOP (Aspect-oriented Programming).

Here’s how to use the outbox library:

First, You will need to annotate the call to the external system using the @Outbox annotation.

@Slf4j
@Service
@RequiredArgsConstructor
public class UseService {

private final RestTemplate restTemplate;
private final UserRepository userRepository;

public void saveUser(UserEntity user) {
userRepository.save(user);
}

@Outbox
public void syncUser(UserEntity user) {
Map<?, ?> map = restTemplate.postForObject("https://gorest.co.in/public/v2/users", user, Map.class);
log.info("response from api: {}", map);
}
}

Second, You just need to call it as if you call a regular method:

@RestController
@RequestMapping("/api")
@RequiredArgsConstructor
public class UserController {

private final UseService useService;

@Transactional
@PostMapping("/users")
public void send(@RequestBody UserEntity user) {
useService.saveUser(user);
useService.syncUser(user);
}
}

Under the hood, the syncUser method call will be serialized to the database, and another background job (using spring-scheduler) will pick that method invocation and invoke it for you.

If you are curious about how this works, you can check the source code of the library at Github, it is Open Source!

Don’t forgive to leave a star! 😉

--

--

Mohammed Hewedy
Mohammed Hewedy

Responses (1)