프론트엔드가 붙으니 비로소 서비스처럼 보였다

백엔드 기능을 어느 정도 완성하고 나니 조금 이상한 기분이 들었다.
이미지 업로드도 된다.
OCR도 동작한다.
사진 안에서 전화번호나 이메일 같은 개인정보도 찾을 수 있다.
EXIF 데이터를 읽어 GPS 위치나 촬영 시간, 기기 정보도 확인할 수 있다.
위험 점수까지 계산해서 JSON으로 정상적으로 내려온다.
개발자인 내가 보기에는 분명히 기능이 만들어지고 있었다.
그런데 화면을 보는 순간 생각이 달라졌다.
브라우저에는 JSON만 있었다.
{
"riskScore": 82,
"riskLevel": "CRITICAL",
"detectedItems": [
{
"type": "PHONE_NUMBER",
"value": "010-****-5678"
}
]
}
기능은 있었지만, 아직 이것을 일반 사용자가 사용할 수 있는 서비스라고 부르기는 어려웠다.
그래서 이번에는 프론트엔드를 붙이기로 했다.
문제는 내가 프론트엔드 개발자가 아니라는 것
나는 주로 Java, Spring MVC, JSP를 사용해 웹 서비스를 개발해왔다.
물론 HTML, CSS, JavaScript를 사용하지 않은 것은 아니다.
JSP 안에서 화면을 만들고 jQuery와 Ajax를 사용해 서버와 데이터를 주고받는 작업도 많이 했다.
하지만 이번처럼
HTML
CSS
Vanilla JavaScript
를 기준으로 화면 전체를 처음부터 설계하는 작업은 익숙하지 않았다.
특히 디자인은 더 어려웠다.
버튼 하나를 어디에 둬야 자연스러운지,
결과 화면에서 어떤 정보부터 보여줘야 하는지,
위험 점수를 숫자로만 보여줄지 그래프로 보여줄지,
모바일에서는 화면을 어떻게 배치해야 할지.
백엔드에서는 기능의 정답이 어느 정도 보이는데 프론트엔드는 선택해야 할 것이 훨씬 많았다.
그래서 이번에는 AI를 적극적으로 사용했다.
ChatGPT에게는 화면의 방향을 맡겼다
먼저 ChatGPT와 프로젝트의 사용 흐름을 정리했다.
사용자가 해야 하는 행동은 사실 단순했다.
사진 선택
↓
분석 버튼 클릭
↓
백엔드 API 호출
↓
분석 결과 확인
페이지가 여러 개 필요한 서비스도 아니었다.
그래서 React나 Vue 같은 프레임워크를 새롭게 도입하기보다 Spring Boot 안에서 간단하게 프론트엔드를 구성하기로 했다.
구조는 이렇게 잡았다.
src
└─ main
└─ resources
└─ static
├─ index.html
├─ style.css
└─ app.js
index.html은 화면의 구조,
style.css는 디자인,
app.js는 API 호출과 화면 변경을 담당하도록 역할을 분리했다.
이 구조를 잡고 나니 생각보다 단순했다.
HTML부터 시작했다
처음에는 정말 최소한의 화면부터 만들었다.
<input
type="file"
id="imageInput"
accept="image/*"
/>
<button id="analyzeButton">
분석하기
</button>
사진을 선택하고 분석 버튼을 누르는 것이 전부였다.
하지만 여기서부터 사용자의 입장에서 생각하기 시작했다.
사진을 어디에 올려야 하는지 바로 알 수 있어야 하고,
현재 선택한 사진이 무엇인지 보여줘야 하고,
분석 중인지 완료됐는지도 알려줘야 한다.
그래서 단순한 파일 입력창을 업로드 영역으로 바꿨다.
┌───────────────────────────────┐
사진을 업로드하세요
JPG / PNG / WEBP
[ 사진 선택하기 ]
└───────────────────────────────┘
[ 분석하기 ]
드래그 앤 드롭도 가능하도록 만들었다.
그제야 조금씩 서비스처럼 보이기 시작했다.
JavaScript가 백엔드와 프론트엔드를 연결했다
개인적으로 이번에 가장 재미있었던 부분이다.
예전에 JSP 기반 개발을 할 때는 서버가 화면 생성에 많이 관여했다.
이번에는 역할이 훨씬 명확했다.
Spring Boot는 데이터를 전달하고,
JavaScript가 데이터를 받아 화면을 변경한다.
예를 들어 이미지 분석 API를 호출하는 부분은 이런 구조다.
async function analyzeImage() {
const file = imageInput.files[0];
const formData = new FormData();
formData.append("image", file);
const response = await fetch("/api/analyze", {
method: "POST",
body: formData
});
const result = await response.json();
renderResult(result);
}
백엔드에서
{
"riskScore": 82,
"riskLevel": "CRITICAL"
}
이라는 응답이 오면 JavaScript가 이것을 화면에 표시한다.
riskScore.textContent = result.riskScore;
riskLevel.textContent = result.riskLevel;
사실 코드 자체만 보면 복잡하지 않다.
하지만 이 연결이 되는 순간 꽤 재미있었다.
내가 만들어놓은 Java API가 처음으로 일반 사용자가 볼 수 있는 화면과 연결됐기 때문이다.
Claude는 구현 보조로 사용했다
ChatGPT와는 화면 구조와 사용자 흐름을 계속 이야기했다면 Claude는 구현 과정에서 코드 단위로 많이 활용했다.
예를 들어
이 부분을 조금 더 정리할 수 있을까?
JavaScript 이벤트 처리가 중복되는데
함수를 어떻게 나누는 게 좋을까?
CSS에서 모바일 화면이 무너지는 이유가 뭘까?
같은 질문을 던졌다.
AI에게 전체 프로젝트를 통째로 맡긴 것은 아니다.
내가 먼저
이 화면에는 무엇이 필요한가?
이 기능은 왜 필요한가?
백엔드 데이터는 어떤 구조인가?
를 결정하고,
구현하면서 막히는 부분을 AI에게 계속 물어봤다.
ChatGPT와 Claude를 번갈아 사용하다 보니 재미있는 점도 있었다.
같은 문제를 물어봐도 접근 방식이 조금씩 달랐다.
그중에서 내가 이해할 수 있고 현재 프로젝트에 맞는 코드를 선택해서 적용했다.
결국 AI가 코드를 작성했다기보다는
AI와 계속 대화하면서 내가 코드를 완성했다
는 표현이 더 맞는 것 같다.
디자인보다 먼저 고민한 것은 접근성이었다
화면을 만들면서 한 가지는 꼭 지키려고 했다.
보기에 예쁜 것만으로 끝내지 않는 것.
예를 들어 클릭할 수 있는 요소라면
<div onclick="analyze()">
분석하기
</div>
보다
<button type="button">
분석하기
</button>
처럼 의미에 맞는 태그를 사용하는 것이 좋다.
이미지에도 필요한 경우 alt 설명을 넣고,
입력 요소에는 label을 연결했다.
<label for="imageInput">
분석할 사진 선택
</label>
<input
id="imageInput"
type="file"
accept="image/*"
/>
한국에는 장애인차별금지법과 웹 접근성 기준이 있고 해외 서비스에서도 접근성은 중요한 부분이다.
이번 프로젝트 규모에서는 작은 부분일 수 있지만 처음부터 습관으로 가져가고 싶었다.
화면 하나가 생겼을 뿐인데 프로젝트가 완전히 달라졌다
사실 기능이 추가된 것은 거의 없다.
백엔드는 어제와 똑같이 동작한다.
OCR도 그대로이고 개인정보 탐지 로직도 그대로다.
그런데 화면 하나가 붙었을 뿐인데 느낌이 완전히 달라졌다.
어제까지는
API 프로젝트
였다면,
오늘부터는
사용자가 직접 사용할 수 있는 서비스
처럼 보이기 시작했다.
사진을 선택한다.
분석 버튼을 누른다.
Spring Boot API가 호출된다.
OCR과 메타데이터 분석이 진행된다.
그리고 결과가 다시 화면에 나타난다.
내가 만든 각각의 기능이 하나의 흐름으로 연결됐다.
프론트엔드를 잘해야만 서비스를 만들 수 있는 것은 아니었다
사실 시작하기 전에는 프론트엔드가 조금 부담스러웠다.
나는 여전히 CSS보다 Java 코드가 편하다.
디자인 감각도 뛰어난 편이라고 생각하지 않는다.
하지만 이번에 다시 느낀 것은 하나다.
모든 것을 잘해야만 시작할 수 있는 것은 아니었다.
내가 아는 백엔드 지식을 중심에 두고,
모르는 부분에서는 ChatGPT에게 구조를 물어보고,
Claude에게 구현 방법을 확인하고,
코드를 직접 실행하고 수정했다.
그리고 결국 화면이 만들어졌다.
AI가 개발자를 대신한다는 이야기를 많이 듣는다.
지금 내가 느끼는 것은 조금 다르다.
AI는 내가 잘 모르는 영역까지 들어갈 수 있게 해주는 도구에 더 가까웠다.
프론트엔드에 익숙하지 않은 Java 개발자가
HTML을 만들고,
CSS를 수정하고,
JavaScript로 API를 연결하고,
결국 실제로 사용할 수 있는 화면까지 만들었다.
예전 같았으면 프론트엔드를 더 공부한 다음 시작해야 한다고 생각했을지도 모르겠다.
이번에는 반대로 했다.
만들면서 배웠다.
그리고 화면을 완성하고 나서 처음으로 이런 생각이 들었다.
프론트엔드가 붙으니 비로소 서비스처럼 보였다.
'RE:개발자' 카테고리의 다른 글
| RE:개발자 — 다시 개발자가 되어가는 기록 | 전체 목차 (0) | 2026.09.20 |
|---|---|
| AI를 붙이면 끝일 줄 알았다, 실제 테스트는 달랐다 | RE:개발자 #8 (0) | 2026.09.19 |
| OCR로 개인정보를 찾기 시작했다, 하드코딩을 걷어낸 날 | RE:개발자 #6 (0) | 2026.09.18 |
| Spring Boot로 REST API를 만들었는데, 아직 아무것도 분석하지 않았다 | RE:개발자 #5 (0) | 2026.09.17 |
| Spring Boot 실행 버튼을 누르면 실제로 무슨 일이 일어날까? | RE:개발자 #4 (0) | 2026.09.17 |