spring webflux with protobuf

Spring WebFlux With Protobuf

Overview:

In this tutorial, I would like to show you how we could use Spring WebFlux with Protobuf (Protocol Buffers) for your RESTful Microservices.

Protocol Buffers, in short Protobuf, are Google’s language-neutral, platform-neutral, extensible mechanism for serializing structured data. You can take a look at this to learn more about this.

Spring WebFlux With Protobuf:

By default Spring Web/WebFlux modules use JSON for exchanging messages & the corresponding message converter. Spring also offers ProtobufHttpMessageConverter for us to use Protobuf if required.

Lets create a simple CRUD application with just GET and POST mappings to demo REST APIs using Spring WebFlux with Protobuf messages.

Sample Application:

We would create a simple Spring application is for managing persons with following dependencies.

spring webflux protobuf

Person Proto:

I define the Person proto as shown here.

syntax = "proto3";

option java_multiple_files = true;
option java_package = "com.vinsguru.models";

message Person {
  string name = 1;
  int32 age = 2;
}

Person Repository:

I use a Map as a database in this example and I create a PersonRepository as shown here.

@Service
public class PersonRepository {

    private final AtomicInteger atomicInteger = new AtomicInteger(1);
    private Map<Integer, Person> personMap;

    @PostConstruct
    private void init(){
        this.personMap = new HashMap<>();
        this.addPerson(Person.newBuilder().setName("vins").setAge(100).build());
    }

    public void addPerson(Person person){
        this.personMap.put(atomicInteger.getAndIncrement(), person);
    }

    public Person getPerson(Integer id){
        return this.personMap.getOrDefault(id, Person.getDefaultInstance());
    }

}

Person Controller:

Lets expose REST APIs for the Person type created using Protobuf.

@RestController
@RequestMapping("person")
public class PersonController {

    @Autowired
    private PersonRepository personRepository;

    @GetMapping("{id}")
    public Person getPerson(@PathVariable int id){
        return this.personRepository.getPerson(id);
    }

    @PostMapping
    public void createPerson(@RequestBody Person person){
        this.personRepository.addPerson(person);
    }

}

That’s it!  At this point, you can start your application which exposes REST API with Protobuf. (Do remember that Protobuf is NOT JSON or text format). You might not be able to test your APIs using browser as we do normally with JSON.

So I create a JUnit test and use WebClient to test the APIs as shown here.

@SpringBootTest
class RestAPIWithProtobufTest {

    private WebClient webClient;

    @BeforeAll
    private void setWebClient(){
        this.webClient = WebClient.builder()
                .baseUrl("http://localhost:8080/person/")
                .build();
    }

    @Test
    void getPersonTest() {
        StepVerifier.create(this.getPerson(1))
                .expectNextCount(1)
                .verifyComplete();
    }

    @Test
    void savePersonTest() {

        // create person
        Person sam = Person.newBuilder()
                .setName("sam")
                .setAge(10)
                .build();

        // save
        Mono<Void> mono = this.webClient.post()
                .bodyValue(sam)
                .retrieve()
                .bodyToMono(Void.class);

        // confirm if it saves
        StepVerifier.create(mono)
                .verifyComplete();

        //  retrieve and verify
        StepVerifier.create(this.getPerson(2))
                .expectNextMatches(p -> p.getAge() == 10)
                .verifyComplete();

    }

    private Mono<Person> getPerson(int id){
        return this.webClient.get()
                .uri("{id}", id)
                .retrieve()
                .bodyToMono(Person.class)
                .doOnNext(p -> System.out.println(p.toString()));
    }

}

Summary:

We were able successfully demonstrate Spring WebFlux with Protobuf.  I am able to GET Person object and POST a protobuf Person object successfully. Spring also allows to have both JSON and Protobuf messages in a same application which is interesting!

The source code is available here.

Learn more about WebFlux:

Happy coding 🙂

Share This:

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.