protoc
Install
Encode / Decode
encode message
decode message WITHOUT .proto file
decode message WITH .proto file
Development
Create java object from proto file
Curl call
Call proto endpoint and get data
Call proto endpoint and send data payload creation
api call
curl -X POST --data-binary @article.payload -H "Content-Type: application/x-protobuf" http://localhost:8080/article/
Data
article.proto
syntax = "proto3";
package michalszalkowski;
option java_package = "com.michalszalkowski.protomolecule";
option java_outer_classname = "ProtoObj";
message Article {
int32 id = 1;
string title = 2;
Author author = 3;
}
message Author {
int32 id = 1;
string first_name = 2;
string last_name = 3;
string email = 4;
repeated PhoneNumber phone = 5;
message PhoneNumber {
string number = 1;
PhoneType type = 2;
}
enum PhoneType {
MOBILE = 0;
LANDLINE = 1;
}
}
article.txt
id: 1
title: "Test"
author: {
id: 1
first_name: "Michal"
last_name: "Szalkowski"
email: "no-valid@michalszalkowski.com"
}
Tools
- https://github.com/qaware/protocurl (not tested)
- BApp Store -> Protobuf Decoder (https://portswigger.net/bappstore/bd8c70d3f1b74679b2a9fed03d36e81a)
Code Snippets
pom.xml
...
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.25.3</version>
</dependency>
</dependencies>
...
package com.michalszalkowski.protomolecule;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.http.converter.protobuf.ProtobufHttpMessageConverter;
@SpringBootApplication
public class ProtomoleculeApplication {
public static void main(String[] args) {
SpringApplication.run(ProtomoleculeApplication.class, args);
}
@Bean
public ProtobufHttpMessageConverter protobufHttpMessageConverter() {
return new ProtobufHttpMessageConverter();
}
}
package com.michalszalkowski.protomolecule;
import org.springframework.web.bind.annotation.*;
@RestController
public class ArticleRestController {
private final ArticleRepository articleRepository = new ArticleRepository();
@GetMapping("/article/{id}")
public ProtoObj.Article getArticle(@PathVariable Integer id) {
return articleRepository.getArticle(id);
}
@PostMapping("/article/")
public ProtoObj.Article creteArticle(@RequestBody ProtoObj.Article article) {
System.out.println("Title = " + article.getTitle());
System.out.println("FirstName = " + article.getAuthor().getFirstName());
System.out.println("LastName = " + article.getAuthor().getLastName());
return article;
}
}
package com.michalszalkowski.protomolecule;
import org.springframework.stereotype.Repository;
import java.util.HashMap;
import java.util.Map;
@Repository
public class ArticleRepository {
private final Map<Integer, ProtoObj.Article> articles = new HashMap<>();
public ArticleRepository() {
ProtoObj.Article course1 = ProtoObj.Article.newBuilder()
.setId(1)
.setTitle("First article about Lorm Ipsum")
.setAuthor(getAuthor())
.build();
ProtoObj.Article course2 = ProtoObj.Article.newBuilder()
.setId(2)
.setTitle("Second article about Lorm Ipsum")
.setAuthor(getAuthor())
.build();
this.articles.put(course1.getId(), course1);
this.articles.put(course2.getId(), course2);
}
private static ProtoObj.Author getAuthor() {
return ProtoObj.Author.newBuilder()
.setId(1)
.setFirstName("Michal")
.setLastName("Szalkowski")
.setEmail("no-valid@michalszalkowski.com")
.addPhone(
ProtoObj.Author.PhoneNumber
.newBuilder()
.setNumber("000-111-222")
.setType(ProtoObj.Author.PhoneType.MOBILE)
.build()
)
.addPhone(
ProtoObj.Author.PhoneNumber
.newBuilder()
.setNumber("333-444-555")
.setType(ProtoObj.Author.PhoneType.LANDLINE)
.build()
)
.build();
}
public ProtoObj.Article getArticle(int id) {
return articles.get(id);
}
}