Mars Rover — 화성의 눈으로 보는 진짜 사진
NASA 화성 로버가 실제로 촬영한 사진을 브라우저에서 탐색하는 갤러리 — RSS 피드 파싱, 세션 캐시, 카메라 필터
시작 — 화성의 눈
Curiosity와 Perseverance는 매일 수백 장의 사진을 지구로 전송합니다. NASA는 이 사진들을 RSS 피드로 공개하고 있습니다.
이 페이지는 그 피드를 파싱해서, 원하는 Sol(화성일)과 카메라를 선택하면 로버가 실제로 촬영한 사진을 바로 볼 수 있게 합니다. 합성 이미지가 아닌, 진짜 화성의 표면입니다.
NASA RSS Feed API
NASA의 mars.nasa.gov는 JSON 기반 RSS 피드를 제공합니다. 로버명, Sol 번호, 페이지 수를 쿼리하면 해당 조건의 이미지 목록이 반환됩니다.
// URL 빌드 — 미션 코드로 로버를 구분
const MISSION_MAP: Record<RoverName, string> = {
curiosity: 'msl',
perseverance: 'mars2020',
};
function buildUrl(rover: RoverName, sol: number): string {
const mission = MISSION_MAP[rover];
return `${RSS_BASE}?feed=raw_images&category=${mission}&feedtype=json&num=100&page=0&sol=${sol}`;
}
개발 환경에서는 Next.js rewrite 프록시(/api/mars-rss)를 경유하고, 프로덕션에서는 NASA 서버에 직접 요청합니다. CORS 문제를 우회하기 위한 구조입니다.
데이터 정규화
NASA 피드의 이미지 객체는 camera.instrument, image_files.small/medium/large/full_res 등 중첩 구조입니다. UI에서 쓰기 편한 flat 구조로 변환합니다.
function mapPhoto(img: MarsRssImage, idx: number): MarsPhoto {
return {
id: img.imageid ?? `${img.sol}_${idx}`,
sol: img.sol,
cameraName: img.camera.instrument,
cameraFullName: CAMERA_NAMES[img.camera.instrument] ?? img.camera.instrument,
imgSrc: img.image_files.medium || img.image_files.small,
fullResSrc: img.image_files.full_res || img.image_files.large,
earthDate: img.date_taken_utc?.split('T')[0] ?? '',
credit: img.credit,
};
}
카메라 코드(FHAZ_RIGHT_A, MCZ_LEFT 등)는 사람이 읽을 수 있는 이름(Front Hazard Cam Right, Mastcam-Z Left)으로 매핑합니다. Curiosity와 Perseverance는 카메라 명칭 체계가 다르므로 두 세트를 모두 관리합니다.
세션 캐시
같은 Sol을 반복 조회할 때 매번 네트워크 요청을 보내지 않도록, sessionStorage에 결과를 캐싱합니다.
const CACHE_PREFIX = 'mars_cache_';
function cacheKey(rover: RoverName, sol: number, camera?: string): string {
return camera ? `${rover}_${sol}_${camera}` : `${rover}_${sol}`;
}
sessionStorage는 탭을 닫으면 사라지므로 영속적 저장 부담이 없습니다. SSR 환경에서는 typeof sessionStorage === 'undefined' 가드를 걸어 서버 사이드 에러를 방지합니다.
카메라 필터
하나의 Sol에는 여러 카메라의 사진이 섞여 있습니다. uniqueCameras() 함수로 해당 Sol에 존재하는 카메라 목록을 추출하고, 칩 UI로 필터링할 수 있게 합니다.
사용자가 특정 카메라를 선택하면, 전체 목록에서 해당 카메라의 사진만 필터링해서 보여줍니다. 카메라별 시점 차이를 비교할 수 있어, 같은 위치의 다른 렌즈 사진을 나란히 보는 경험을 제공합니다.
라이트박스
사진 카드를 클릭하면 full-res 이미지를 오버레이로 표시합니다. backdrop-filter: blur(8px)로 배경을 흐리게 처리하고, 하단에 카메라명과 촬영 날짜를 표시합니다.
원본 이미지를 새 탭에서 열 수 있는 링크도 제공합니다. NASA 이미지는 퍼블릭 도메인이므로 자유롭게 사용할 수 있습니다.
마치며
화성은 이제 상상의 대상이 아닙니다. 매일 새로운 사진이 지구에 도착합니다. 이 페이지는 그 사진들을 가장 빠르게 접할 수 있는 창구를 목표로 했습니다.
Sol 번호를 바꿔가며 화성의 계절이 변하는 모습을 보는 것, 다른 카메라로 같은 장소를 보는 것 — 작은 조작만으로도 화성 탐사의 일부가 됩니다.