작업 배경
우리 팀의 서버 개발 히스토리와 상황은 다음과 같다.
- 최초 express.js로 개발 -> Nest.js 도입하여 express는 라우트 연결하여 유지, 새 기능은 Nest.js로 개발
- express.js: shecma-first(graphQL 스키마를 직접정의), Seqeulize
- Nest.js: code-first(graphQL 스키마를 코드로 정의한 뒤 생성), prisma
- Apollo GraphQL 기반
- 이전에 개발된 express 의 공고 스크랩 API
- 최근에 개발된 Nest.js 의 관심기업 설정 API
작업
전략
요구사항은 공고를 스크랩할 때 해당 공고의 기업에 관심설정을 하도록 하는 것이다. 아래에 채택되지 않은 방안과 제약을 정리해보았다.
- 클라이언트에서 두 API를 각각 호출: 구버전 앱에서 호환되지 않음
- express 로직에서 Nest.js API를 호출: 한 서버 프로세스에서 불필요한 네트워크 호출
- express 코드를 모두 Nest.js로 작성: 공고달력, 팔로우 등 많은 기능과 얽혀있기에 검증이 어려워 서비스에 영향을 줄 수 있음
결론적으로는 위 두 방안이 아닌 Nest.js 기반의 엔드포인트와 인풋/아웃풋 타입을 정의하고, 내부에서 express 서비스 함수를 호출하고도록 하였다. 이 전략은 다음과 같은 장점과 한계를 가진다.
장점
- Apollo express 서버는 요청 context 에 서비스 클래스를 포함한다는 점을 활용하여 쉽게 구현할 수 있다
- 코드 기반을 Nest.js 로 구성하여 Nest.js의 가드, 미들웨어, 인터셉트와 같은 인프라 기능을 활용할 수 있다
- GraphQL 스키마를 코드로 관리하여 스키마 관리가 용이
단점
- express 코드에서는 sequelize 를 사용하고 Nest.js 코드에서 prisma 를 사용하고 있기에, 트랜잭션으로 처리하기 위하여 별도의 처리가 필요하다.
참고한 글
코드 샘플
- 기존 공고 스크랩 API
// src/resolvers/mutation.js
const resolvers = {
Mutation: {
activityScrap: async (_, { input }, context) => {
// 1. Apollo Context에서 서비스 추출
const { userScrapService } = context;
// 2. 공고 스크랩
const result = await userScrapService.updateUserScrap(input);
return result;
}
}
}
- 새 공고 스크랩 API
// src/scraps/resolvers/user-scraps.resolver.ts
@Resolver(() => UserScrapDto)
export class UserScrapsResolver {
constructor(private scrapsService: ScrapsService) {}
@Mutation(() => ScrapPayloadDto, { nullable: true })
async activityScrap(
@Context() context: RequestContext,
@Args('input') input: ScrapInputDto,
) {
return await this.scrapsService.updateActivityScrap(context, input)
}
}
// src/scraps/services/user-scraps.service.ts
public async updateActivityScrap(
context: RequestContext,
input: ScrapUpdateInputDto,
): Promise<ActivityScrapUpdatePayloadDto | null> {
// express 서비스 함수
const { userScrapService } = context
const result = await userScrapService.updateUserScrap(input);
// Nest.js 서비스 함수
await this.companyInterestService.setCompanyInterestedIn(
context,
compnayId
);
return result
}
향후 계획
순수 비즈니스 로직 또한 모듈 단위, 함수 단위로 나누어 NestJS Service로 하나씩 추출할 예정이다.
'배운 것들 > 프로그래밍' 카테고리의 다른 글
| Event Driven Architecture 고찰 - (1) 왜 필요한가? (2) | 2026.03.13 |
|---|---|
| Building Event Driven Microservices 북스터디 (0) | 2025.12.31 |