우아한테크코스 8기 precourse

JSON DTO Converter 오픈 미션 회고록

hwangsoojin 2025. 11. 24. 08:07

"내 능력 밖의 과제라고 느꼈지만, 결국엔 해냈다!!"

 

오픈 미션에 대해서 설명해주는 라이브 방송이 그 시작이었다.

라이브 방송에서 "오픈 미션이 뭘 하는 미션일 것 같으세요?"라고 물어봤을 때

댓글에서는 꽤 많은 사람들이 그 의도를 맞추는 모습이었다.

나는 감도 잡지 못 했는데.. "오픈"이 그런 의미였구나!

등골이 오싹해졌지만 그것은 사람들의 추측에 불과하기를 바랐다.

얼마 지나지 않아 오픈 미션에서는 무엇을 하는 것인지 설명해주셨고

사람들의 추측은 정답이었다. 몇 초 동안 아무 말도 나오지 않았다...
프리코스 1~3주차도 분명히 쉽지만은 않았지만, 적어도 명확한 요구사항과 틀이 있었다.
그런데 이번 미션은 달랐다 ...

"미션 주제는 자유롭게 정한다.
스스로 도전하고 싶은 목표를 설정하고, 그에 맞는 실행 계획을 세워 미션을 진행한다."


아무도 나에게 "이렇게 만들어라"라고 말해주는 사람이 없었다.

 

그 사실이 나를 엄청나게 압박했고 엄청난 시간을 잡아먹게 되었다.
"내가 무엇을 만들어야 하지?
무엇을 기준으로 설계해야 하지?"

 

프리코스를 하면서 처음으로 '막막함'이라는 감정이 명확하게 찾아왔다.


0. 주제는 모르겠고... 하기 싫었던 것에 도전해보자!

이번 오픈 미션의 주제는 "도전"이라고 하였다.

그래서 어떤 것을 구현할지 주제를 정하기 전에

내가 무의식 속에 "부담스럽다, 하기 싫다, 피하고 싶다"라고

느껴왔던 것이 무엇이 있는지부터 생각해보았다.

이번 오픈 미션에서는 평소에 하기 싫어했던 것을 해보기로 마음 먹었기 때문이다.

 

컴퓨터과학부에 다니면서 개발 경험은 여러번 쌓을 기회가 있었지만

그때마다 API 통신과 JSON 파싱은 늘 역할 분담에서 벗어나는 편이었다.

그래서 API 문서를 읽어보고, 그에 맞춰 코드를 작성하는 프로그래밍에 대해서

막연한 두려움을 가지고 있었다.

 

그래서 이번 미션에서는 주제가 무엇이 되었든 외부 API와 통신하여

무언가를 개발해보는 경험을 쌓아보자는 결심을 하게 되었다. 


1. 내가 일부러 피하고 살아온 부분과 마주한 순간

JSON이 무엇인지는 당연히 안다!

백엔드 개발을 하면서 프론트엔드와 JSON 데이터를 주고 받는 것은 필수적이니까!

 

하지만 솔직히 말하면, 겁이 났다.

외부 API라는 것이 뭔가 미지의 세계처럼 느껴졌다.

그들이 요구하는 형식에 맞추기 위해 API 문서를 읽고,

코드로 그들과의 통신을 하고 그들이 주는 JSON 데이터....

뭔지 모를 막연함이 있었다.

 

그래서 적극적으로 외부 API를 이용한 개발 방법에 대해서

검색하고 공부하기 시작했다.

미션을 위해 여러 API 문서를 일부러 찾아서 읽어보고,

JSON 예시를 직접 분석하였다.

일부러 여러 API 문서를 읽어보면서 '아 이거 무슨 말이야... '라는

생각이 들 때는 "아, 내가 이걸 계속 피해와서 익숙치 않구나"라는

사실을 인정해야 했다.

 

하지만 이것도 계속 반복하다보니

'아 이것도 별 게 아니구나?'라고 느껴지는 순간이 찾아왔다.  

막연하게 두려웠던 과거와 정면으로 맞서는 순간이었다.


"아, 내가 이걸 계속 피해왔구나"라는 사실을 인정해야 했다.


2. JSON → DTO 변환 규칙을 발견하던 순간

ChatGPT로 예시 JSON 을 받아보고 이것의 구조를 천천히 해석해보며

Java의 DTO 클래스로 바꾸는 연습을 해보던 어느 날,
문득 아주 일관된 규칙이 보이기 시작했다.

  • {} 하나는 클래스
  • "key": value 는 필드
  • {} 안에 {} 가 있으면 내부 클래스
  • [] 안에 {} 여러 개가 있으면 List<T>

이 구조가 눈에 들어오는 순간
내 머릿속에서 갑자기 하나의 문장이 떠올랐다.

"이게 아주 일관된 규칙이 있네...
그렇다면 이 과정을 자동으로 만들 수 있지 않을까?"

 

이런 생각이 떠오르면서

주제도 정하지 않고 개발 방법만 조사하던 나에게
처음으로 주제 확신이 생겼다.

그리고 이것이 오픈 미션 전체를 이끌어간 “핵심 아이디어”가 됐다.

"JSON 하나만 주어지면
DTO 클래스를 자동으로 만들어주는 기능을 만들어 보자!"

3. 문제 요구사항 정의조차 힘들었다

다른 사람들은 멋진 주제를 빠르게 정해나가는 것처럼 보였는데
나는 스스로에게 끊임없이 물어봐야 했다.

"사용자에게 입력은 어떻게 받아야 하지?"
=> JSON 파일로? 단순 문자열로?

"JSON을 DTO로 바꿨다고 하자.. 그럼 이 결과를 어떻게 리턴해야 하지?"
=> Java 파일로? 단순 문자열로?

UI는 어떻게 꾸며야 하는가?
=> CLI? GUI?

.
.

 

아이디어를 떠올리는 것보다 요구사항을 '정의'하는 과정이 더 힘들었다.

어떤 것을 만들어야겠다는 아이디어를 떠올렸다고 하더라도

그 아이디어를 구현해야 할 때 어느 선까지 구현을 해야할지

그 경계까지도 내가 직접 설정해주어야 했기 때문에 하루 이틀은 우습게 지나갔다.

"내가 괜히 어려운 걸 하려는 건가?"라는 생각이 들 정도로 압박감이 쌓였지만, 이상하게도 멈출 수가 없었다.

이 아이디어를 끝까지 구현하려면 지금까지 프리코스에서 배운 것의

모든 능력을 총동원해야 한다는 느낌이 들었기 때문이다.

문자열 파싱, 예외 처리, 입력 검증, 객체지향 분리, 테스트 작성…

하나라도 소홀히 하면 전체 구조가 무너질 것 같은 프로젝트였다. 그래서 오히려 확신이 들었다.

어렵기 때문에, 바로 그래서 이 주제가 나에게 가장 잘 맞는 도전이라고.


4. 구현을 시작하기 전… 자료 조사만 하다가 1주일이 지나 있었다

아이디어는 분명히 있었고,
"JSON을 DTO 클래스로 자동 변환하는 프로그램"이라는 목표도 정해졌다.

오랜 시간이 걸렸지만 요구사항도 스스로 정의하여

이제 코드를 작성하기만 하면 되었다.


하지만 막상 개발을 시작하려고 하면 손이 떨어지지 않았다.
왜냐하면, 무엇부터 만들어야 하는지조차 불명확했기 때문이다.

JSON을 어떻게 파싱해야 하는지,
파싱된 결과를 어떤 구조로 담아야 하는지,
필드 타입은 어떻게 추론해야 하는지,
이 모든 정보를 어떻게 하나의 Java 클래스 구조로 만들어야 하는지…

 

이것을 위해서 인터넷에 어떤 키워드로 검색해야 할지도 모르는 상태였다.

그래서 자료 조사만 몇 날 며칠을 계속했다.
Jackson 공식 문서를 처음부터 끝까지 읽고,
StackOverflow 답변 수백 개를 뒤지고,
그러다가 발견한 JSON Schema라는 개념도 다시 공부하고,
다른 언어의 타입 추론기를 참고해보고,
여러 자동 생성 툴의 동작 방식까지 분석했다.

문제를 해결하려고 검색하다 보면
또 다른 개념이 튀어나오고,
그 개념을 이해하다 보면 그다음 개념을 공부해야 해서
메모장에는 "공부해야 할 개념 목록"만 끝없이 늘어갔다.

 

그러다 보니
오픈 미션이 시작된 지 정확히 1주일 동안 단 한 줄의 코드도 작성하지 못했다....

이 시기가 가장 불안했다.

  • 다른 사람들은 이미 기능을 하나씩 만들고 있는데
  • 나만 여전히 "설계"라는 이름의 정체된 곳에서 헤매고 있고
  • 내가 방향을 제대로 잡은 건지 확신도 없고
  • 그냥 너무 어려운 걸 골라버린 건 아닌가 싶고…

그럼에도 불구하고 자료조사, 공부를 멈출 수 없었던 이유는 하나였다.
이 복잡한 개념들을 이해해야만 이 프로젝트를 제대로 만들 수 있다고 생각했기 때문이다.

 

돌이켜보면,
그 1주일은 시간 낭비가 아니라,
이 프로젝트의 가장 중요한 기반을 만든 시간이었다.

이 기간 덕분에 이후의 모든 설계를 흔들림 없이 진행할 수 있었다.


5. 본격 구현 시작… CLI부터 JSON까지 연결하는 과정은 전쟁 같았다

자료 조사가 끝났다고 해서 바로 손이 풀린 건 아니었다.

구현을 시작하자마자 또 다른 문제들이 쏟아졌다.

 

CLI 프로그램을 직접 만든다는 것이 이렇게 어렵구나라는 걸 뼈저리게 느꼈다.

특히 CLI 인자 파싱 단계가 생각보다 훨씬 복잡했다.

  • 값이 없는 옵션을 어떻게 검증할 것인지
  • 사용자 오류를 어떻게 감지하고 안내할 것인지
  • 옵션과 값 사이에 '=' 표기를 허용할지 말지
  • 상대·절대 경로를 어떻게 처리해야 하는지

한 줄 한 줄이 고민의 연속이었다.

 

CLI Parser를 완성한 뒤에는
JSON Validator라는 더 큰 산이 기다리고 있었다.

  • 파일이 실제로 존재하는지
  • 디렉터리인지 아닌지
  • 5MB를 넘지 않는지
  • BOM이 있는 경우 어떻게 처리해야 하는지
  • JSON 문법이 잘못된 경우 어떤 메시지를 출력해야 하는지
  • 루트가 객체 또는 배열인지 어떻게 판정해야 하는지

이 모든 조건을 엮어 정확한 오류 메시지를 반환해야 했다.

 

정말 말 그대로
프로젝트 전체가 전쟁 같았다.


6. JSON Analyzer와 TypeInferencer를 만들면서 사고방식이 완전히 바뀌었다

이번 미션에서 내 사고방식이 가장 크게 바뀐 순간은
JSON Analyzer와 TypeInferencer를 만드는 과정이었다.

 

JSON을 어떻게 분석해야 할까?
입력 구조를 어떻게 "정적인 타입의 세계"로 옮길 수 있을까?

 

이 질문에 답하려면
그동안 배운 개념보다 더 넓게 사고해야 했다.

 

그 구조를 분석하는 과정은 CLI 명령어 파싱과 마찬가지로 파싱의 연속이었다.
그리고 파싱 결과를 기반으로 "타입"을 추론하는 과정은
작은 컴파일러의 일부 단계와 매우 유사했다.

 

처음엔 배열 안에 여러 타입이 들어있는 상황을 처리하지 못해 멘붕이 왔고,
optional 필드를 판단하기 위한 presenceCount 로직을 설계하는 데만
반나절이 넘게 걸렸다.

 

이 과정에서 나는 처음으로
"아, 내가 지금 구조를 만드는 개발을 하고 있구나"
라고 느꼈다.

 

그리고 더 놀라운 것은,
이 복잡한 로직들이 하나씩 동작하기 시작하며
"JSON이 Java 타입으로 자연스럽게 바뀌어가는" 순간이었다.

 

손으로 JSON을 읽고 DTO를 만들던 방식에서,
나의 논리와 내가 세운 규칙으로 데이터 구조가 바뀌는 것을 볼 때
이 개발 과정에서 경이로움을 느꼈다.


7. 설계가 얼마나 중요한지 뼈저리게 느꼈다

JSON 분석과 타입 추론을 끝냈을 때
“이제 절반 정도는 왔겠지?”라고 생각했지만,
막상 다음 단계에 들어서니 그 생각이 얼마나 말도 안 되는 건지 바로 깨달았다.

 

JSON에서 어떤 정보가 어떤 형태로 들어 있는지까지 알게 된 건
말 그대로 입력 데이터의 해석이 끝났다는 것일 뿐이었다.

 

그런데 프로그램이 실제로 해줘야 하는 일은
"해석한 데이터를 기반으로 실제 Java 클래스를 설계하고, 파일 형태로 출력하는 것"이다.

 

  • 어떤 이름의 클래스를 만들어야 자연스러운지
  • 서로 다른 위치에 동일한 구조가 나타나면 하나의 클래스로 묶어야 할지, 아니면 별도로 만들어야 할지
  • 필드 간의 관계를 어떻게 정리해야 하는지
  • 클래스 이름이 충돌한다면 어떻게 해결해야 하는지
  • CLI에서 입력받은 옵션 값에 따라 전체 구조를 어떻게 구성해야 하는지

이 모든 것을 직접 설계해야 한다는 사실이 나를 엄청난 무게로 압도했다.

아.. 역시 나에겐 너무 어려운 과제였어..

 

설계하는 과정에서 빈약한 설계로 열심히 작성했던 코드를

다시 갈아엎어야 했던 순간은 한두번이 아니었다.

 

대표적인 예로

  • user → { name, email, phone }
  • manager → { name, email, department }

이 두 구조를 처음 봤을 때, 필드 이름이 일부 겹치니까
나는 너무 쉽게 "아, 둘 다 같은 구조로 보이는데?

그냥 하나의 공통 클래스로 묶자"라고 결정해버렸다.

 

그러나 실제 구현 단계에서 문제는 바로 드러났다.

둘 다 name, email이 있다는 이유만으로 묶어버리면,
manager에 필요한 department 필드는 어디에 넣어야 하지?
user에는 없는 필드인데 같은 곳에 넣어도 될까?


클래스를 나누면 중복이라서 찜찜하고,
하나로 합치면 또 구조가 어색해진다.

 

결국 내가 놓친 건 단 하나였다.

"겉보기로 필드가 비슷하다고 해서, 그것들이 같은 개념은 아니다."

 

그래서 이미 절반 넘게 구현된 코드를 전부 엎어야 했다.
중간에 억지로 해결하려다 보니 어느 순간 코드가 점점 이상해졌다.

  • 어떤 건 user를 참조하고
  • 어떤 건 manager를 참조하고
  • 어떤 곳은 공통 클래스를 참조하고…

서로 엮이기 시작하면서 코드 전체가 퍼즐 조각이 서로 안 맞는 상태처럼 되어갔다.

이걸 더 끌고 가면 결국 전체 프로젝트가 망한다는 걸 알아차리고,
하루 밤을 꼬박 새며 구조를 다시 설계했다.

 

그때 절실히 깨달았다.

"설계는 단순히 효율을 위해 필요한 것이 아니라,
개발시간을 단축해주고 프로젝트 전체를 살리는 기반이라는 것을" 

8. 개발 중 겪은 트러블슈팅… 지금 생각해도 아찔한 순간들

이 프로젝트는 기능 구현 외에도
수십 개의 예상치 못한 문제들과 싸워야 했다.

특히 기억에 남는 순간들:

  • gradlew가 사라져서 다른 프로젝트에서 복붙해온 일
  • Manifest 설정을 제대로 하지 않아 JAR가 실행되지 않았던 일
  • 외부 라이브러리가 JAR에 포함되지 않아 "ClassNotFound"가 터졌던 일
  • 빌드 스크립트 구조를 잘못 잡아서 계속 실패했던 일
  • Windows CMD에서 경로 인코딩 문제로 옵션 처리가 꼬였던 일

이 문제들을 해결하는 과정은 솔직히 개발보다 더 힘들었고,
좌절감과 스트레스도 훨씬 컸다.

 

그 다음 단계로 넘어가고 싶은데 계속된 에러로 넘어가지지가 않으니!!!

 

하지만 지금 돌아보면,
이 경험들이 나를 더 단단하게 만들었다.

 

"문제가 왜 생겼는지"를 찾는 과정에서
Gradle 구조, JAR 패킹 방식, 클래스패스 개념,
심지어 운영체제별 경로 처리 차이까지 자연스럽게 배우게 되었다.

 

이 트러블슈팅들은 이 프로젝트가 단순 "기능 구현"에 그치지 않고

나를 전반적으로 성장시킨 이유였다.


9. 우테코에서 배운 컨벤션을 지키며 한 줄 한 줄 다시 작성한 시간들

매주차 공통 피드백을 거의 외우다시피 보면서 코드를 작성했다.
특히 아래 내용들이 이번 오픈 미션에서 아주 강력하게 작용했다.

  • 메서드는 한 가지 일만 하게 만들기
  • 줄 수가 길어지면 로직을 분리하기
  • 상수는 static final로 관리하기
  • 테스트 가능한 구조로 만들기
  • 과도하게 뭉친 기능 나누기
  • 하드코딩 지양하기
  • 클래스 멤버 순서 지키기 (상수 → 변수 → 생성자 → 메서드)
  • Git commit 컨벤션 지키기
  • 기능 단위로 테스트 진행하기

이 규칙들을 억지로 적용하는 것이 아니라
"적용해야 코드가 계속 파악 가능해지는 상황"을 처음 경험했다.

 

특히 ArgumentParser를 만들 때는
처음엔 단순히 if-else로 전부 때려 넣으려다
너무 복잡해져서 결국 다시 갈아엎었다.

 

또 TypeInferencer를 구현하면서
"optional한 필드 처리 로직",
"array 요소 타입 간 union 처리 로직"
이런 복잡한 판단들이 쌓이기 시작했다.

이러한 기능들을 하나의 클래스 내에 그대로 두면

절대 테스트 불가능했다.

 

그래서 책임 단위별로 조각내기 시작했고,
그 과정에서 자연스럽게 컨벤션이 나를 가이드해줬다.

 

한 줄씩, 한 메서드씩 정리하면서 스스로에게 계속 말했다.

"미래의 나와 리뷰어가 읽을 코드를 만들자..."


분명히 내가 작성하는 코드에 대한 태도 자체가 바뀌었다.


10. 스스로 가장 잘했다고 느끼는 점

무조건 기능을 먼저 만드는 방식이 아니라
전체 구조를 먼저 설계하고 책임을 나눴던 점
내가 가장 잘한 선택이었다고 생각한다.

 

만약 기능 구현부터 들어갔다면
중간에 구조가 틀어져 모든 파일을 갈아엎는 상황이
무조건 왔을 것이다.

물론 구조를 갈아엎는 상황은 몇 번 나왔지만...

그 구조 설계와 책임을 나누는 과정이 선행되었으니

그 정도에서 끝난 것이라고 생각한다... ^^  

 

또 하나 스스로 칭찬하고 싶은 점은
실패했을 때 "왜 실패했는지"를 반드시 기록하고
반드시 해결하고 지나갔다는 부분이다.

  • CLI 파싱 구조
  • JSON Validator의 책임 분리
  • SchemaNode 계층 설계
  • 타입 추론 로직
  • 클래스 생성 템플릿

이 모든 과정에서
한 번도 "그냥 넘어가는 선택"을 하지 않았다.

 

작은 디테일 하나라도
"이게 정말 맞는가?"를 스스로 계속 검증하며 나아갔다.

 

이러한 태도 덕분에
최종적으로는 흔들리지 않는 구조를 만든 것 같다.


11. 프리코스를 마무리하며

이 5주 동안 나는
학교 수업, 과제, 대외활동, 프로젝트, 프리코스를 동시에 병행했다.

몸이 정말 힘든 날도 많았고
하루에 잠을 2~3시간밖에 못 잔 날도 많았다.

결국 지하철 통학 중에 꾸벅꾸벅 졸면서 총 수면 시간을

어느 정도 채운 감이 없지 않지만..! 

 

하지만 어느 날 문득,
"그래도 나 정말 많이 성장했구나…"라는 생각이 들었다.

 

처음에는 두려움뿐이었지만 이 미션을 끝까지 완성하고 나니
오히려 내 한계를 더 넓혔다는 느낌이 들었다.

 

프리코스 동안 받은 피드백은

내 개발 방식과 사고방식을 완전히 바꿔놓았고,
이 오픈 미션은 그 모든 변화를 종합해서
하나의 결과물로 만들어낸 경험이었다고 생각한다.

 

그리고 무엇보다,
이 마지막 미션은 나에게 이렇게 말해준 것 같다.

 

"너는 새로운 영역을 두려워하면서도 결국에는 끝까지 해내는 사람이구나."

 

이 경험을 잊지 않고, 우테코에서든 그 이후의 개발자로서 삶에서도
내 성장을 스스로 증명해나가고 싶다.

 

5주..인 줄 알았던 6주.... 프리코스를 경험한 스스로에게

너무 고생많았다며 칭찬해주고 싶다!!!!!!!!

 

그래도 되돌아보면 매주매주 늘어가는 실력에 행복했던 것 같던...

그래서 마냥 힘들지만은 않았던 것 같던...