
백엔드 개발자는 무슨 일을 할까?
요즘 Java로 알고리즘 문제를 풀고 있다. 문제를 읽고, 조건에 맞는 풀이를 생각하고, 코드를 작성해 결과를 확인하는 과정에는 조금씩 익숙해지고 있다.
이제는 그동안 공부한 내용을 하나의 서비스로 연결해 보고 싶어졌다. 이번에 만들어 보려는 것은 재고 CSV 파일을 검사하고 정해진 형식으로 바꿔 주는 서비스, DataCheck다. 아직 구현 전이며, 앞으로 이 프로젝트를 진행하면서 백엔드와 관련된 개념을 함께 공부해 보려고 한다.
파일을 읽고 잘못된 값을 찾는 기능은 Java 프로그램 하나로도 만들 수 있다. 그런데 여러 사용자가 웹에서 파일을 올리고, 이전 결과를 다시 확인하고, 실패한 작업을 재실행하도록 하려면 어떤 일이 더 필요할까?
첫 글에서는 이 질문을 출발점으로 백엔드 개발자의 책임을 정리해 봤다.
어떤 서비스를 만들려고 하는가
DataCheck는 정해진 재고 CSV를 업로드하면 잘못된 데이터와 그 이유를 알려주고, 정상 데이터만 표준 형식으로 내려받게 하는 서비스다. CSV는 쉼표로 필드를 구분하는 텍스트 기반 데이터 형식이다. 따옴표로 감싼 값에는 쉼표나 줄바꿈도 들어갈 수 있어서, 단순히 쉼표마다 문자열을 잘라서는 정확하게 읽을 수 없다.
첫 버전은 품목 코드, 품목명, 수량, 창고 코드, 기록일이라는 다섯 열만 지원하려고 한다. 엑셀 파일이나 임의의 양식을 모두 처리하려고 하면 처음부터 범위가 너무 넓어질 것 같아 UTF-8 CSV 한 종류로 정했다.
예를 들어 수량이 음수라면 해당 행을 오류로 분류하고, 날짜가 2026/09/16이라면 실제로 존재하는 날짜인지 확인한 뒤 2026-09-16으로 바꾼다. 품목명에 쉼표가 들어 있어도 하나의 값으로 보존해야 한다. CSV 전용 파서가 파일의 구조를 읽고, 내가 작성할 검증기는 각 값이 업무 규칙에 맞는지 판단하도록 나눌 생각이다. Apache Commons CSV의 파싱·출력 설명
사용자는 로그인하고 파일을 제출한 뒤 진행 상태를 확인한다. 검사가 끝나면 정상 결과와 오류 보고서를 내려받고, 나중에 자신의 작업 이력을 다시 조회한다.
아직 실제 사용자의 반복 수요를 확인한 것은 아니다. 우선 합성 데이터로 기능과 실패 상황을 검증하는 학습 프로젝트로 시작하려고 한다.
클라이언트와 서버: 파일을 보내는 쪽과 처리하는 쪽
클라이언트(client)는 다른 프로그램의 기능이나 데이터를 요청하는 쪽이고, 서버(server)는 그 요청을 받아 처리하고 결과를 제공하는 쪽이다.
DataCheck에서는 사용자가 접속한 브라우저가 클라이언트 역할을 한다. 브라우저는 선택한 파일을 서버로 보내고, 이후 작업 상태나 결과 파일을 요청한다. 서버는 요청한 사용자를 확인하고, 파일을 보관하고, 검사를 진행하며, 요청에 맞는 응답을 돌려준다.
‘서버’라는 말은 프로그램과 컴퓨터를 모두 가리킬 수 있다. ‘Java로 서버를 만든다’고 할 때는 요청을 처리하는 프로그램을, ‘서버에 파일을 보관한다’고 할 때는 그 프로그램이 사용하는 컴퓨터나 저장 환경을 뜻하는 경우가 많다. 내 노트북에서 서버 프로그램과 브라우저를 함께 실행해도 둘의 역할은 구분된다.
통신에는 요청과 응답의 형식을 정한 약속이 필요하다. 웹에서 사용하는 대표적인 약속이 HTTP다. 파일을 보낸다는 행동도 실제로는 파일 내용을 담은 HTTP 요청으로 전달된다. 다만 모든 요청이 끝날 때까지 파일 검사도 반드시 끝나 있어야 하는 것은 아니다.
이 프로젝트에서 특히 구분해야 할 것이 ‘접수되었다’와 ‘검사가 끝났다’다.
파일을 오래 검사해야 한다면 서버는 원본을 저장하고 작업 정보를 DB에 남긴 뒤, 우선 작업 ID를 돌려줄 수 있다. 이후 별도의 처리 코드가 검사를 수행하고 브라우저는 작업 ID로 상태를 조회한다. 이런 구조에서 접수 응답을 받았다는 것은 작업이 등록됐다는 뜻이다. 정상 결과를 내려받을 수 있다는 뜻은 아니다.
처음에는 요청이 끝나기 전에 검사까지 수행하는 동기 방식으로 만들어 보고, 기능이 맞게 동작하면 요청 접수와 실제 처리를 분리할 예정이다. 기다리는 흐름을 바꾸는 것이므로, 비동기로 바꿨다고 검사 알고리즘 자체가 빨라지는 것은 아니다.
프런트엔드와 백엔드: 화면에 보이는 상태는 어디에서 결정될까?
프런트엔드(frontend)는 사용자가 서비스를 보고 조작하는 부분을 구현한다. DataCheck에서는 파일 선택창, 업로드 버튼, 작업 목록, 오류 미리보기, 다운로드 버튼이 여기에 해당한다.
겉모양을 만드는 것 외에도 할 일이 있다. 제출 중 버튼이 여러 번 눌리지 않게 하고, 파일을 고르지 않았다면 안내하고, 서버가 알려준 작업 상태에 맞게 화면을 바꾸는 일도 프런트엔드가 담당한다.
백엔드(backend)는 요청을 해석하고, 서비스의 규칙에 맞게 처리하며, 필요한 데이터와 상태를 관리한다. 파일 크기를 검사하고, 사용자와 작업을 연결하고, 검사를 실행하며, 어떤 결과를 다운로드하도록 허용할지 결정하는 일이 여기에 해당한다.
프런트엔드에서 파일 크기를 확인하더라도 서버의 검사는 필요하다. 사용자가 화면 코드를 바꾸거나, 브라우저 대신 다른 도구로 직접 요청할 수도 있기 때문이다. 화면의 검사는 사용자에게 빠르게 안내하기 위한 것이고, 서버의 검사는 실제로 받아들여도 되는 요청인지 판단하기 위한 것이다.
다운로드 버튼을 숨기는 것만으로 다른 사람의 파일 접근을 막을 수도 없다. 버튼이 없어도 다운로드 주소로 직접 요청할 수 있으므로, 파일을 제공하는 순간 서버에서 소유권을 확인해야 한다.
두 영역은 API(Application Programming Interface)라는 접점을 통해 협력한다. API는 프로그램이 다른 프로그램의 기능을 어떤 방법으로 요청하고 어떤 결과를 받을지 정한 인터페이스다.
이 서비스에서는 ‘파일을 제출하면 작업 ID를 받는다’, ‘작업 ID로 현재 상태와 집계를 조회한다’, ‘성공한 작업의 결과를 요청하면 파일을 받는다’는 약속이 필요하다. 프런트엔드는 이 약속을 바탕으로 화면을 구성하고, 백엔드는 약속한 의미에 맞는 상태와 결과를 제공한다.
따라서 완료 화면을 보여주는 시점도 단순한 디자인 문제가 아니다. 업로드가 끝난 순간 화면에 ‘검사 완료’를 표시하면 실제 처리 상태와 어긋날 수 있다. 백엔드가 접수·진행·완료를 구분하고, 프런트엔드가 그 의미를 유지해야 한다.
클라이언트·서버가 통신에서의 역할을 설명한다면, 프런트엔드·백엔드는 구현의 관심사와 책임을 설명한다. 서버에서 화면을 만들어 보내는 방식도 있으므로 두 구분을 완전히 같은 뜻으로 외우지는 않으려고 한다.
비즈니스 규칙: 어떤 데이터를 정상으로 볼 것인가
비즈니스 규칙(business rule)은 서비스가 다루는 업무에서 지켜야 하는 조건과 정책이다. 여기서 비즈니스는 돈을 버는 활동만 뜻하지 않는다. DataCheck에서는 재고 데이터를 검사하고 정리하는 일이 서비스의 업무다.
‘수량은 0 이상의 정수여야 한다’, ‘품목 코드는 비어 있으면 안 된다’, ‘날짜는 실제로 존재해야 한다’는 조건이 규칙이다. 잘못된 행이 발견됐을 때 전체 파일을 거절할지, 그 행만 제외할지도 업무 규칙에 해당한다.
이 프로젝트에서는 개별 행의 값이 잘못된 경우 해당 행만 정상 결과에서 제외하고, 오류 보고서에 이유를 남기기로 했다. 하지만 헤더가 다르거나 CSV 구조가 깨져 내용을 신뢰할 수 없다면 파일 전체를 실패로 처리한다. 앞부분에 정상처럼 보이는 행이 있어도 완성된 결과로 공개하지 않는다.
같은 품목·창고·기록일이 반복되면 첫 번째 정상 행만 채택한다. 단순히 파일에서 먼저 나타났다는 이유만으로 잘못된 행을 기준으로 삼지는 않는다. 날짜 형식과 정해진 공백 처리를 먼저 적용한 뒤 중복 키를 비교해야 표현만 다른 같은 데이터를 구분할 수 있다.
예를 들어 아래는 네 레코드를 검사할 때 기대하는 결과다. 아직 실행 결과가 아니라, 구현이 맞는지 확인하기 위해 먼저 정한 기준이다.
| 레코드 | 입력의 특징 | 기대 결과 |
|---|---|---|
| 1 | P-001, 정상 수량, WH-A, 2026/09/16 | 정상. 날짜를 2026-09-16으로 변환 |
| 2 | P-002, 빈 품목명, 음수 수량, WH-A, 2026-09-16 | 오류 행 1개, 오류 항목 2개 |
| 3 | P-001, 정상 수량, WH-A, 2026-09-16 | 1번과 같은 키이므로 중복 오류 |
| 4 | P-002, 정상 품목명·수량, WH-A, 2026-09-16 | 정상. 2번은 잘못된 행이므로 이 키의 첫 정상 행은 4번 |
전체는 4행, 정상은 2행, 오류는 2행이다. 오류 항목은 2번의 두 문제와 3번의 중복 문제를 합쳐 3개다. 오류 행 수와 오류 항목 수는 서로 다르다.
이런 규칙을 실제 판단과 처리 순서로 옮긴 부분을 비즈니스 로직(business logic)이라고 한다. 입력을 정리하고, 필수값과 범위를 검사하고, 정상 후보의 중복을 판단한 뒤 출력 대상을 나누는 과정이 여기에 해당한다.
CSV 라이브러리가 따옴표나 쉼표를 읽어 주더라도, 음수 수량을 허용할지와 중복 중 무엇을 남길지는 대신 결정해 주지 않는다. 코드를 작성하기 전에 정책과 기대 결과를 정리해야 하는 이유다.
영속성: 검사 결과와 작업 이력은 어디에 남을까?
영속성(persistence)은 프로그램 실행이 끝난 뒤에도 데이터를 보존하고 다시 사용할 수 있는 성질이다.
검사 결과를 Java의 ArrayList에만 담아 두면 실행 중에는 사용할 수 있다. 하지만 프로세스를 종료하고 다시 시작했을 때 이전 목록이 자동으로 돌아오지는 않는다. 사용자가 다음 날 작업 이력을 확인하거나 결과를 다시 내려받으려면 메모리 밖에 정보를 남겨야 한다.
이번 프로젝트에서는 파일과 DB가 서로 다른 정보를 보관한다. 원본 CSV, 정상 결과 CSV, 전체 오류 보고서는 파일로 남긴다. DB에는 누가 제출했는지, 파일이 어디에 있는지, 작업 상태가 무엇인지, 언제 어떤 시도로 처리했는지와 같은 정보를 저장한다.
이처럼 데이터에 관한 설명을 메타데이터(metadata)라고 한다. 파일의 저장 키, 크기, 소유자, 생성 시각은 파일 내용 자체가 아니라 파일을 관리하기 위한 정보다. 결과 행을 하나씩 검색하는 기능이 지금 필요하지 않으므로 모든 CSV 행을 DB에 저장하지 않을 생각이다.
사용자가 요청한 하나의 검사를 ‘작업’으로, 실제로 처리한 한 번을 ‘시도’로 나누는 것도 중요하다. 서버 오류 때문에 재실행하면 같은 작업 아래 두 번째 시도가 생긴다. 첫 번째 실패 기록을 지워 버리면 무슨 문제가 있었는지 설명하기 어려워진다.
여기서 주의할 점은 파일 저장과 DB 저장이 자동으로 함께 성공하거나 취소되지는 않는다는 것이다. 결과 파일을 만드는 데 성공했지만 DB에 완료 상태를 기록하기 전에 서버가 종료될 수도 있다. 반대로 DB에 파일 경로가 있어도 실제 파일이 없어질 수 있다.
DB의 트랜잭션(transaction)은 여러 DB 변경을 하나의 처리 단위로 관리한다. 변경을 확정하는 것을 커밋(commit), 취소하는 것을 롤백(rollback)이라고 한다. 하지만 일반적인 DB 트랜잭션을 취소했다고 별도로 작성한 파일까지 자동으로 삭제되지는 않는다. MySQL의 커밋·롤백 설명
따라서 결과 파일은 임시 위치에 작성하고, 처리가 끝난 뒤 확정 위치로 옮기며, DB에도 결과 참조와 성공 상태를 함께 기록하는 방식으로 설계하려고 한다. 사용자에게는 성공 상태로 확정된 결과만 제공한다. 그 사이에 생긴 불필요한 파일을 어떻게 찾아 정리할지도 별도로 필요하다.
영속성은 모든 파일을 영원히 보관한다는 뜻은 아니다. 이번 서비스에서는 기본 7일 보관 정책을 두고, 실행 중인 작업은 삭제 대상에서 제외할 예정이다. 파일이 만료됐다는 상태와 검사가 실패했다는 상태도 구분해야 한다.
보안: 내 파일을 다른 사람이 볼 수 없어야 한다
보안(security)은 데이터와 기능을 허용되지 않은 접근이나 변경으로부터 보호하는 일이다. 파일 검사 서비스에서는 사용자가 제출한 파일과 결과가 다른 사용자에게 노출되지 않도록 하는 것이 중요한 책임이다.
인증(authentication)은 요청한 주체가 누구인지 확인하는 과정이다. 인가(authorization)는 확인된 주체가 특정 행동을 할 권한이 있는지 판단하는 과정이다. 로그인에 성공했더라도 다른 사용자의 파일을 내려받을 권한까지 얻는 것은 아니다.
사용자 A와 B가 각각 파일을 제출했다고 가정해 보자. B가 A의 작업 ID를 알아냈더라도 상세 정보와 결과 파일을 볼 수 없어야 한다. 재실행 요청 역시 차단해야 한다. 요청에 적힌 사용자 번호를 그대로 믿지 않고, 서버가 검증한 로그인 정보와 저장된 작업의 소유자를 비교해야 한다.
파일 자체도 확인해야 한다. 확장자가 .csv라고 해서 형식이 올바르거나 안전한 것은 아니다. 허용한 크기인지, 지원하는 형식으로 읽을 수 있는지 검사해야 한다. 사용자가 보낸 파일명을 저장 경로로 그대로 사용하지 않고, 서버가 만든 저장 키로 비공개 위치에 보관하는 방식을 사용할 예정이다. OWASP의 파일 업로드 보호 지침
결과를 CSV로 내려주는 과정에도 살펴볼 점이 있다. 자유 텍스트에 수식으로 해석되는 값이 들어 있으면 스프레드시트에서 파일을 열 때 원래 의도와 다르게 동작할 수 있다. 오류 보고서에 원본 값을 그대로 복사하는 경우도 마찬가지다.
다만 모든 값에 임의의 문자를 붙이면 다른 프로그램이 읽을 데이터까지 달라진다. 기계가 처리할 값과 사람이 볼 표시용 값을 구분하고, 어떤 프로그램에서 안전성을 확인했는지 기록해야 한다. 모든 스프레드시트와 재저장 방식에 통하는 만능 처리라고 가정하지 않으려고 한다. OWASP의 CSV Injection 설명
신뢰성: 오류가 있어도 결과의 의미는 정확해야 한다
신뢰성(reliability)은 정해진 조건에서 서비스가 기대한 기능을 일관되게 수행하는 성질이다. 이 프로젝트에서는 올바른 파일을 잘 처리하는 것과 함께, 잘못된 데이터나 서버 중단을 만났을 때 어떤 상태를 남기는지도 중요하다.
먼저 데이터 오류와 서버 장애를 구분해야 한다. 음수 수량을 찾아 오류 보고서에 남기는 것은 검증기가 해야 할 일을 수행한 결과다. 일부 행이 잘못되었더라도 검사가 끝났다면 ‘완료, 오류 있음’으로 표시할 수 있다. 데이터 행은 있는데 정상 행이 하나도 없는 경우도 여기에 포함한다.
반면 결과를 쓰다가 저장 장치 오류가 나거나 처리 도중 서버가 종료됐다면 검사를 정상적으로 끝내지 못한 것이다. 이런 상태를 완료로 표시하거나 미완성 결과를 내려주면 사용자는 잘못된 결과를 믿게 된다.
작업 상태는 다음처럼 구분할 예정이다.
| 상태 | 의미 |
|---|---|
| QUEUED | 원본과 작업 정보가 접수되어 처리를 기다리는 중 |
| RUNNING | 워커가 작업을 가져가 처리하는 중 |
| SUCCEEDED | 검사 완료, 모든 행 정상, 확정 결과 제공 가능 |
| SUCCEEDED_WITH_ERRORS | 검사 완료, 오류 행이 있으며 정상 결과와 오류 보고서 제공 가능 |
| FAILED | 파일 구조 문제 또는 서버 오류 등으로 전체 처리를 완료하지 못함 |
FAILED라는 상태만 보고 모두 재실행해서는 안 된다. 날짜나 파일 구조가 잘못됐다면 같은 입력을 다시 처리해도 해결되지 않는다. 사용자가 파일을 수정해 새 작업으로 제출해야 한다. 서버 오류로 실패한 경우에만 같은 원본으로 다시 실행하도록 하고, 실패 원인 코드를 함께 남길 생각이다.
중복 요청도 신뢰성과 연결된다. 사용자가 업로드를 눌렀지만 응답을 받지 못해 다시 보냈다고 하자. 서버에서는 첫 번째 요청을 이미 접수했을 수 있다. 이때 요청마다 새 작업을 만들면 같은 제출 의도가 여러 작업으로 늘어난다.
이를 구분하기 위해 하나의 제출 의도에는 같은 요청 키를 사용한다. 같은 사용자·같은 키·같은 내용이면 기존 작업을 알려주고, 같은 키인데 내용이 바뀌었다면 충돌로 안내한다. 반대로 사용자가 의도적으로 새 작업을 만들었다면 파일이 같더라도 허용한다. 파일 내용이 같은 것과 요청이 중복된 것은 다른 문제다.
서버가 처리 중 종료된 경우에도 기준이 필요하다. 이번에는 한 애플리케이션과 한 워커로 범위를 제한하고, 완전히 종료된 뒤 재시작했을 때 남은 실행 중 작업을 실패로 정리하려고 한다. 이후 사용자가 새로운 시도로 전체 재실행할 수 있게 한다. 중간 레코드부터 이어서 처리하는 기능은 첫 목표에 넣지 않았다.
개발과 운영: 만든 기능을 계속 사용할 수 있게 하기
개발은 요구사항을 정리하고 코드를 작성하며 의도한 동작인지 검증하는 일이다. DataCheck에서는 정상 CSV 하나를 변환하는 것과 함께, 여러 오류가 있는 행이나 잘못된 헤더도 예상한 방식으로 처리하는지 확인해야 한다.
배포(deployment)는 만든 프로그램을 사용자가 접근하는 환경에 반영하는 일이다. 내 컴퓨터에서는 되던 기능도 파일 경로, DB 연결, 메모리 제한, 폴더 권한이 달라지면 동작하지 않을 수 있다. 실행 환경을 정리하고 배포한 뒤 실제 흐름을 확인하는 일도 필요하다.
운영(operations)은 제공 중인 서비스의 상태를 살피고 변경과 장애에 대응하는 일이다. 파일 검사 서비스에서는 대기 작업이 계속 쌓이지 않는지, 실패가 늘지 않는지, 보관 파일이 저장 공간을 모두 차지하지 않는지 살펴야 한다.
로그(log)는 프로그램에서 일어난 사건의 기록이다. 작업 ID, 시도 번호, 상태 변화, 오류 코드와 소요 시간을 남기면 특정 작업이 어디서 멈췄는지 추적할 수 있다. 원본 행 전체나 비밀번호까지 기록할 필요는 없다.
모니터링(monitoring)은 서비스 상태를 지속적으로 확인하는 활동이다. 작업 대기 수, 실패 수, 처리 시간, 사용 중인 저장 공간을 관찰하면 문제가 생겼는지 판단하는 데 도움이 된다. 모니터링할 값도 ‘있으면 좋아 보이는 수치’보다 실제로 어떤 조치를 결정하는 데 쓸지를 생각하며 고르려고 한다.
성능을 설명할 때도 측정이 필요하다. 파일을 접수하는 데 걸린 시간과 검사를 끝내는 데 걸린 시간을 따로 보고, 같은 데이터로 반복 측정해야 한다. 처음 설정한 20 MiB·10만 행 제한은 검증을 위한 초기 상한이며, 지금 그 규모를 충분히 처리한다고 확인한 수치는 아니다.
파일을 한꺼번에 읽지 않고 레코드 단위로 읽으면 메모리 부담을 줄일 수 있다. 그래도 중복 판정용 Set에는 고유 키가 남기 때문에 모든 메모리 사용이 일정해진다고 말할 수는 없다. 개선 결과도 실제로 측정한 조건과 함께 기록할 예정이다.
운영 책임에는 복구 가능한 범위를 설명하는 일도 포함된다. 영속 볼륨을 사용하면 앱을 다시 실행할 때 파일을 유지할 수 있지만, 그것만으로 저장 장치 장애에 대비한 백업까지 갖춘 것은 아니다. 이번 프로젝트에서 확인한 재시작 복구와 아직 보장하지 못하는 상황을 구분해야 한다.
백엔드 개발자 한 사람이 모든 인프라와 보안을 혼자 담당한다는 뜻은 아니다. 팀마다 역할은 다르다. 다만 내가 만든 코드가 어디에 상태를 남기고, 어떤 조건에서 실패하며, 운영 중 무엇을 확인해야 하는지는 이해할 필요가 있다.
이 서비스에서 나눠야 할 책임
| 사용자 행동·상황 | 프런트엔드의 역할 | 백엔드의 역할 |
|---|---|---|
| 파일 제출 | 파일 선택과 제출 상태를 보여준다. | 사용자·허용 크기·입력을 확인하고 파일과 작업을 접수한다. |
| 작업 상태 확인 | 접수·대기·처리·완료·실패를 구분해 표시한다. | 저장된 상태와 확인된 집계를 제공한다. |
| 오류 확인 | 데이터 레코드 번호와 이유를 읽기 쉽게 보여준다. | 행 오류와 전체 실패를 구분하고 오류 항목과 행 수를 정확히 집계한다. |
| 결과 다운로드 | 제공 가능한 결과와 만료 여부를 안내한다. | 소유권·완료 상태·확정 결과·보관 상태를 확인한다. |
| 같은 요청 재전송 | 같은 제출에는 같은 요청 키를 사용한다. | DB 제약과 요청 지문으로 중복 접수를 통제한다. |
| 타인 작업 접근 | 허용된 메뉴와 결과만 보여준다. | 직접 보낸 요청도 검사해 조회·다운로드·재실행을 차단한다. |
| 처리 중 서버 종료 | 다음 조회에서 실패 상태와 가능한 행동을 안내한다. | 미완성 결과를 공개하지 않고 실패 이력을 보존한다. |
이 표를 정리하면서, 파일을 바꾸는 규칙 외에도 정해야 할 약속이 많다는 것을 알게 됐다. 상태와 응답의 의미를 정하는 일도 구현의 일부다.
알고리즘 공부와 어떻게 이어질까?
알고리즘 문제에서는 정해진 입력 조건 안에서 정확하고 효율적인 결과를 구하는 데 집중한다. DataCheck에서도 자료구조와 시간 복잡도는 필요하다. 중복 키를 찾는 Set, 결과를 순서대로 처리하는 방식, 데이터 크기에 따른 메모리 사용량이 지금까지 공부한 내용과 연결된다.
여기에 서비스에서는 입력 형식이 잘못될 수 있고, 같은 요청이 동시에 들어올 수 있으며, 실행이 끝난 뒤에도 파일과 이력이 남아야 한다는 조건이 붙는다. 결과 계산뿐 아니라 그 결과를 누가 보고, 언제 공개하며, 실패하면 무엇을 남길지도 정해야 한다.
앞으로 기능을 하나 만들 때마다 ‘정답이 나오는가’와 함께 ‘이 요청을 허용해도 되는가’, ‘데이터가 어디에 남는가’, ‘중간에 멈추면 어떤 상태가 되는가’를 확인하려고 한다.
이번 글에서 정리한 것
| 개념 | 뜻 | DataCheck에서의 활용 |
|---|---|---|
| 클라이언트·서버 | 요청하는 쪽과 처리·응답하는 쪽 | 브라우저가 파일을 보내고 서버가 작업을 접수·처리한다. |
| 프런트엔드·백엔드 | 사용자 상호작용과 규칙·데이터 처리의 책임 구분 | 화면은 상태를 표현하고 서버는 실제 상태·권한·결과 공개를 판단한다. |
| 비즈니스 규칙·로직 | 지켜야 할 정책과 이를 적용하는 처리 과정 | 행 검증, 첫 정상 행 채택, 오류 집계, 재실행 허용 조건을 구현한다. |
| 영속성 | 실행 이후에도 데이터를 보존하고 재사용하는 성질 | 파일은 원본·결과를, DB는 소유자·작업·시도 이력을 보관한다. |
| 보안 | 허용되지 않은 접근과 변경으로부터 보호 | 로그인뿐 아니라 작업별 소유권, 저장 위치, 내보내기를 검사한다. |
| 신뢰성 | 정해진 조건에서 기대한 기능과 결과의 의미를 유지 | 접수와 완료를 구분하고, 중복 요청과 중단에도 미완성 결과를 공개하지 않는다. |
| 개발·운영 | 기능을 만들고 검증하며 실제 환경에서 유지·복구 | 테스트·배포·로그·성능 측정·파일 정리와 복구 범위를 관리한다. |
백엔드 개발에는 요청을 처리하는 코드와 함께, 무엇을 정상으로 볼지, 데이터를 어디에 남길지, 실패했을 때 사용자에게 무엇을 알려줄지 정하는 일도 포함된다. 이번 프로젝트에서는 이 책임을 파일 하나가 들어와 결과로 나가는 흐름 안에서 직접 확인해 보려고 한다.
다음 글에서는 먼저 Spring 없이 Java로 검증기를 만들 예정이다. 한 행의 데이터와 오류를 어떤 객체로 표현할지, 첫 정상 행을 기억하려면 어떤 키를 Set에 넣어야 할지, 오류 항목 수와 오류 행 수를 어떻게 구분할지부터 살펴보려고 한다.
저장은 완료됐는데 응답만 클라이언트에 도착하지 않은 경우 중복 저장을 막으려면 어떤 방법을 사용할 수 있을까요?