HomeAboutMeBlogGuest
© 2025 Sejin Cha. All rights reserved.
Built with Next.js, deployed on Vercel
🤩
개발
/네트워크(Network)/
gRPC
gRPC
/
프로토버프(Protobuf)

프로토버프(Protobuf)

시작하기Rest로 Protobuf 사용하기
notion image
notion image

시작하기

  • 필요한 것
    • .proto 파일 작성
    • proto 컴파일러 [ Github release 페이지 ]로 proto 파일을 Java 클래스로 변환
      • protoc --java_out=java resources/jake.proto
        protoc —java_out=<Java class를 만들 경로> <proto 파일 경로>
        Java class를 만들 경로 + java_package(proto 파일) = 클래스 최종 생성 경로
    • protobuf runtime [ Maven Repository ] (해당 버전과 proto 컴파일러 버전 맞추기!)
      • Java클래스에서 사용되는 라이브러리들을 갖고 있는 의존성
  • .proto 파일
    • syntax = "proto3"; package protobuf; option java_package = "com.uplus.virtualoffice.test"; option java_outer_classname = "SchoolProto"; message Course { int32 id = 1; string course_name = 2; repeated Student student = 3; } message Student { 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; } }
    • .proto 파일에서는 snake_case로 작성했던 것들이 자바 컨벤션에 따라 camelCase로 변환됨
    • repeated : 몇번이고 반복되어 들어갈 수 있다 (List 를 의미)
Type definition error: [simple type, class com.google.protobuf.UnknownFieldSet$Parser]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class com.google.protobuf.UnknownFieldSet$Parser and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS
  • 위와 같은 에러 발생하는 건 MappingJackson2HttpMessageConverter 가 사용되어서 발생하는 에러임. Accept 헤더를 application/x-protobuf 로 추가해서 요청하면 ProtobufMessageConverter 를 사용하게 되어 에러 발생하지 않음

Rest로 Protobuf 사용하기

[ Blog ] Protobuf를 사용하여 BE, FE 구현
[ Github ] Protoman — postman 처럼 구현해놓은 protobuf http api 테스트 툴
@RestController class CourseController(@Autowired val courseRepo: CourseRepository) { @GetMapping(value = ["/courses/{id}"], produces = [MediaType.APPLICATION_PROTOBUF_VALUE]) @ResponseBody fun customer(@PathVariable id: Int): CDSDTraining.Course? { val course = courseRepo.getCourse(id) return course } @PostMapping(value = ["/courses"], consumes = [MediaType.APPLICATION_PROTOBUF_VALUE], produces = [MediaType.APPLICATION_PROTOBUF_VALUE]) @ResponseBody fun coursePost(@RequestBody course: Course?): CDSDTraining.Course? { return course } }
  • produces에 MediaType.APPLICATION_PROTOBUF_VALUE를 추가하면 response가 ProtobufHttpMessageConverter를 거쳐서 protobuf message가 serialize되어 나간다