Open API 기반 서버 코드 맛보기#777
Hidden character warning
Conversation
Choidongjun0830
left a comment
There was a problem hiding this comment.
궁금한 점 있으면 질문 남겨주세요!
There was a problem hiding this comment.
이 파일은 신경쓰지 않으셔도 됩니다.
| private final ArticleService articleService; | ||
|
|
||
| @Override | ||
| public PageArticleResponse getArticles( |
There was a problem hiding this comment.
주의할 점은, x-spring-paginated: true를 붙여도 응답이 Spring의 Page로 자동 생성되지는 않는다는 점입니다. 그래서 컨트롤러에서는 서비스가 반환한 Page를 그대로 노출하는 대신, spec에 정의한 PageArticleResponse로 한 번 변환해서 반환해야 합니다.
| @RequestParam(required = false) @DateTimeFormat(iso = ISO.DATE) LocalDate date, | ||
| @RequestParam(required = false) Long newsletterId, |
There was a problem hiding this comment.
기존에는 query parameter가 2개 이상인 경우 @ModelAttribute로 묶어서 받는 방식을 사용하고 있었습니다. 그런데 이번 맛보기 codegen에서는 그 부분까지 고려하지 않고 우선 생성해본 상태라, 현재는 개별 @RequestParam형태로 내려오고 있습니다. 이전에 올렸던 PR에서는 이 부분을 반영해서, mustache 템플릿을 커스텀하는 방식으로@ModelAttribute 기반 생성이 가능하도록 보완했습니다.
|
|
||
| @Override | ||
| public PageArticleResponse getArticles( | ||
| @LoginMember Member member, |
There was a problem hiding this comment.
PetController와는 다르게, 이쪽은 기존에 사용하던 방식대로 @LoginMember를 그대로 사용할 수 있습니다. 이는 기본 generator 결과가 아니라, 백엔드에서 사용 중인 인증 주입 방식을 유지할 수 있도록 vendor extension과 mustache 템플릿을 커스텀해둔 결과입니다.
There was a problem hiding this comment.
이 클래스는 @LoginMember같은 ArgumentResolver 기반 주입을 사용하지 않을 때, 컨트롤러 내부에서 직접 현재 로그인 사용자를 꺼내기 위해 추가한 Bean입니다. ArgumentResolver는 메서드 파라미터 해석 시점에 동작하는 방식이라, 생성된 시그니처에 @LoginMember를 반영하지 않으면 이런 형태의 별도 인증 조회 코드가 필요해집니다. 다만 현재 백엔드에서는 vendor extension과 mustache 커스텀을 통해 generated API에도 @LoginMember를 사용할 수 있도록 맞췄기 때문에, 최종 방향에서는 이 Bean이 필수는 아닙니다. 이 코드는 PetController에서 “커스텀하지 않으면 어떤 식으로 구현해야 하는지”를 비교해보기 위한 예시 성격으로 들어간 코드입니다.
| return petService.getPet(member); | ||
| public me.bombom.openapi.model.PetResponse getPet() { | ||
| Member member = currentMemberProvider.getCurrentMember(); | ||
| return PetResponseMapper.toApi(petService.getPet(member)); |
There was a problem hiding this comment.
이 Mapper는 Controller 응답으로 나가는 DTO와 Service 반환 DTO를 분리하여서 생긴 것입니다.
기존대로 코드를 작성하면 Mapper는 필요없을 것으로 보입니다.
다만 다시 살펴보면서 든 생각은, 조회 계층에서 DTO projection까지 고려하면 generated DTO를 그대로 사용하는 데 제약이 있을 수 있다는 점입니다. JPQL의 경우에는 select new ...Response(...)형태로 작성할 수 있어서 generated DTO를 대상으로도 큰 문제 없이 사용할 수 있을 것 같습니다. 반면 Querydsl은 기존처럼 record 내부 생성자에@QueryProjection을 붙여 사용하는 방식이라, 자동 생성된 DTO를 그대로 projection 대상으로 쓰기는 어려울 수 있어 보입니다.
그래서 QueryDSL을 사용하는 경우에는 mapper가 필요할 수도 있습니다.
| @Override | ||
| @GetMapping | ||
| public PetResponse getPet(@LoginMember Member member){ | ||
| return petService.getPet(member); | ||
| public me.bombom.openapi.model.PetResponse getPet() { | ||
| Member member = currentMemberProvider.getCurrentMember(); |
There was a problem hiding this comment.
ArticleListController와는 다르게 이쪽은 @LoginMember를 사용하지 않아, 우리가 기존에 구현하던 방식과는 차이가 있습니다.
그래서 generated API를 실제 백엔드 코드에 자연스럽게 녹이기 위해서는, 기존 인증 주입 방식을 유지할 수 있도록 vendor extension과 mustache 템플릿을 커스텀하는 작업이 필요합니다.
There was a problem hiding this comment.
backend/bom-bom-server/generated/openapi/me/bombom/openapi/ 하위의 파일들은 spec에 의해 자동 생성된 산출물입니다.
6205829 to
4aeb821
Compare
|
음 이런느낌 |
이 PR은 머지하려는 목적보다는, codegen으로 생성된 API를 실제 백엔드 코드에 연결했을 때 어떤 식으로 구현되는지 살펴보기 위한 맛보기 성격의 PR입니다. 구조와 흐름을 중심으로 봐주시면 됩니다.
📌 What
OpenAPI codegen으로 생성된 API 인터페이스와 DTO를 실제 백엔드 구현에 연결하는 맛보기 코드를 추가했습니다.
이번 PR에서는 특히 다음 두 흐름을 예시로 붙였습니다.
또한 이 흐름이 실제로 동작하는지 확인할 수 있도록 DB를 사용하는 E2E 테스트도 함께 추가했습니다.
❓ Why
OpenAPI codegen 기반을 붙여두더라도, 실제로 백엔드 코드에서 어떤 형태로 구현해야 하는지 감이 바로 오지는 않았습니다.
특히
@LoginMember방식과 생성된 인터페이스 시그니처를 어떻게 맞출지같은 부분은 코드를 직접 붙여보는 예시가 있어야 비교가 쉬울 것 같아서, 구현 방향을 빠르게 파악할 수 있도록 맛보기 형태로 먼저 올렸습니다.
🔧 How
생성된 코드는 직접 수정하지 않고, 생성 결과를 구현체에서 받아 사용하는 방향으로 맞췄습니다.
backend/bom-bom-server/generated/openapi/me/bombom/openapi/하위의 파일들은 spec에 의해 자동 생성된 산출물입니다.주요 적용 방식은 다음과 같습니다.
PetController는 생성된 PetApi를 구현하도록 변경했습니다.
@LoginMember파라미터 대신CurrentMemberProvider를 통해 현재 로그인 사용자를 조회하는 방식도 함께 비교할 수 있도록 두었습니다.아티클 목록 조회는 생성된 ArticleApi를 구현하는 ArticleListController를 추가하고, 서비스 계층의 기존 응답을 generated DTO(PageArticleResponse)로 변환하는 매퍼를 두었습니다.
PetController, 아티클 목록 조회 API 모두 DB를 사용하는 E2E 테스트를 추가해 실제 요청-응답 흐름과 상태 변경까지 검증했습니다.
👀 Review Point (Optional)
이 PR 자체는 최종 머지 목적보다는, “codegen 기반 API를 실제로 붙이면 이런 느낌이다”를 보여주는 예시 성격이라 그 관점에서 봐주셔도 충분합니다.