# API Explorer 개발 작업 계획 > **작성일**: 2025-12-17 > **기준 문서**: API Explorer 상세 설계서 (api-explorer-spec.md) > **상태**: 🟡 계획 수립 완료 --- ## 📚 참고 문서 ### 핵심 참고 문서 | 문서 | 경로 | 참조 섹션 | |------|------|----------| | **상세 설계서** | [`docs/features/api-explorer-spec.md`](../features/api-explorer-spec.md) | UI 와이어프레임(§5), HTMX 패턴(§8), 보안(§9) | | **OpenAPI 스펙** | `api/storage/api-docs/api-docs.json` | 파싱 대상 JSON | ### 개발 표준 문서 | 문서 | 경로 | 용도 | |------|------|------| | API 개발 규칙 | [`docs/standards/api-rules.md`](../standards/api-rules.md) | Service-First, FormRequest | | 품질 체크리스트 | [`docs/standards/quality-checklist.md`](../standards/quality-checklist.md) | 코드 품질 검증 | ### 기존 코드 참조 | 항목 | 경로 | 용도 | |------|------|------| | mng 레이아웃 | `mng/resources/views/layouts/app.blade.php` | 기존 UI 패턴 | | mng dev-tools | `mng/resources/views/dev-tools/` | 기존 개발 도구 패턴 | | mng 라우트 | `mng/routes/web.php` | 라우트 패턴 | ### 기술 스택 참조 | 기술 | 문서 | 용도 | |------|------|------| | HTMX | [htmx.org/docs](https://htmx.org/docs/) | 동적 UI 업데이트 | | Tailwind CSS | [tailwindcss.com](https://tailwindcss.com/docs) | 스타일링 | | Laravel HTTP | [laravel.com/docs/http-client](https://laravel.com/docs/http-client) | API 프록시 | --- ## 🗄️ 핵심 스키마 (인라인) ### DB 테이블 구조 ```sql -- api_bookmarks: 즐겨찾기 CREATE TABLE api_bookmarks ( id BIGINT PRIMARY KEY AUTO_INCREMENT, user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE, endpoint VARCHAR(500) NOT NULL, method VARCHAR(10) NOT NULL, display_name VARCHAR(100), display_order INT DEFAULT 0, color VARCHAR(20), created_at TIMESTAMP, updated_at TIMESTAMP, UNIQUE KEY (user_id, endpoint, method), INDEX (user_id) ); -- api_templates: 요청 템플릿 CREATE TABLE api_templates ( id BIGINT PRIMARY KEY AUTO_INCREMENT, user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE, endpoint VARCHAR(500) NOT NULL, method VARCHAR(10) NOT NULL, name VARCHAR(100) NOT NULL, description TEXT, headers JSON, path_params JSON, query_params JSON, body JSON, is_shared BOOLEAN DEFAULT FALSE, created_at TIMESTAMP, updated_at TIMESTAMP, INDEX (user_id, endpoint, method), INDEX (is_shared) ); -- api_histories: 요청 히스토리 CREATE TABLE api_histories ( id BIGINT PRIMARY KEY AUTO_INCREMENT, user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE, endpoint VARCHAR(500) NOT NULL, method VARCHAR(10) NOT NULL, request_headers JSON, request_body JSON, response_status INT NOT NULL, response_headers JSON, response_body LONGTEXT, duration_ms INT NOT NULL, environment VARCHAR(50) NOT NULL, created_at TIMESTAMP, INDEX (user_id, created_at), INDEX (endpoint, method) ); -- api_environments: 환경 설정 CREATE TABLE api_environments ( id BIGINT PRIMARY KEY AUTO_INCREMENT, user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE, name VARCHAR(50) NOT NULL, base_url VARCHAR(500) NOT NULL, api_key VARCHAR(500), -- 암호화 저장 auth_token TEXT, -- 암호화 저장 variables JSON, is_default BOOLEAN DEFAULT FALSE, created_at TIMESTAMP, updated_at TIMESTAMP, INDEX (user_id) ); ``` ### 라우트 정의 ```php // routes/web.php - API Explorer 라우트 그룹 Route::prefix('dev-tools/api-explorer') ->middleware(['auth']) ->name('api-explorer.') ->group(function () { // 메인 Route::get('/', 'index')->name('index'); // 엔드포인트 (HTMX partial) Route::get('/endpoints', 'endpoints')->name('endpoints'); Route::get('/endpoints/{operationId}', 'endpoint')->name('endpoint'); // API 실행 Route::post('/execute', 'execute')->name('execute'); // 즐겨찾기 Route::get('/bookmarks', 'bookmarks')->name('bookmarks'); Route::post('/bookmarks', 'addBookmark')->name('bookmarks.add'); Route::delete('/bookmarks/{id}', 'removeBookmark')->name('bookmarks.remove'); Route::put('/bookmarks/reorder', 'reorderBookmarks')->name('bookmarks.reorder'); // 템플릿 Route::get('/templates', 'templates')->name('templates'); Route::get('/templates/{endpoint}', 'templatesForEndpoint')->name('templates.endpoint'); Route::post('/templates', 'saveTemplate')->name('templates.save'); Route::delete('/templates/{id}', 'deleteTemplate')->name('templates.delete'); // 히스토리 Route::get('/history', 'history')->name('history'); Route::delete('/history', 'clearHistory')->name('history.clear'); Route::post('/history/{id}/replay', 'replayHistory')->name('history.replay'); // 환경 Route::get('/environments', 'environments')->name('environments'); Route::post('/environments', 'saveEnvironment')->name('environments.save'); Route::delete('/environments/{id}', 'deleteEnvironment')->name('environments.delete'); Route::post('/environments/{id}/default', 'setDefaultEnvironment')->name('environments.default'); }); ``` ### Config 파일 ```php // config/api-explorer.php return [ // OpenAPI 스펙 파일 경로 'openapi_path' => env('API_EXPLORER_OPENAPI_PATH', base_path('../api/storage/api-docs/api-docs.json')), // 기본 환경 설정 'default_environments' => [ [ 'name' => '로컬', 'base_url' => 'http://api.sam.kr', 'api_key' => env('API_EXPLORER_LOCAL_KEY', ''), ], [ 'name' => '개발', 'base_url' => 'https://api.codebridge-x.com', 'api_key' => env('API_EXPLORER_DEV_KEY', ''), ], ], // 프록시 설정 'proxy' => [ 'timeout' => 30, // 초 'max_body_size' => 1024 * 1024, // 1MB 'allowed_hosts' => [ // 화이트리스트 'api.sam.kr', 'api.codebridge-x.com', 'localhost', ], ], // 히스토리 설정 'history' => [ 'max_entries' => 100, // 사용자당 최대 'retention_days' => 30, // 보관 기간 ], // 보안 설정 'security' => [ 'encrypt_tokens' => true, // API Key/Token 암호화 'mask_sensitive_headers' => [ // 히스토리에서 마스킹 'Authorization', 'X-API-KEY', 'Cookie', ], ], ]; ``` ### Service 메서드 시그니처 ```php // OpenApiParserService - OpenAPI JSON 파싱 class OpenApiParserService { public function parse(): array; // 전체 스펙 파싱 public function getEndpoints(): Collection; // 엔드포인트 목록 public function getEndpoint(string $operationId): ?array; // 단일 엔드포인트 public function getTags(): array; // 태그 목록 public function search(string $query): Collection; // 검색 public function filter(array $filters): Collection; // 필터링 } // ApiRequestService - API 호출 프록시 class ApiRequestService { public function execute( string $method, string $url, array $headers = [], array $query = [], ?array $body = null ): array; // ['status', 'headers', 'body', 'duration_ms'] } // ApiExplorerService - CRUD 통합 class ApiExplorerService { // Bookmarks public function getBookmarks(int $userId): Collection; public function addBookmark(int $userId, array $data): ApiBookmark; public function removeBookmark(int $bookmarkId): void; public function reorderBookmarks(int $userId, array $order): void; // Templates public function getTemplates(int $userId, ?string $endpoint = null): Collection; public function saveTemplate(int $userId, array $data): ApiTemplate; public function deleteTemplate(int $templateId): void; // History public function logRequest(int $userId, array $data): ApiHistory; public function getHistory(int $userId, int $limit = 50): Collection; public function clearHistory(int $userId): void; // Environments public function getEnvironments(int $userId): Collection; public function saveEnvironment(int $userId, array $data): ApiEnvironment; public function deleteEnvironment(int $environmentId): void; public function setDefaultEnvironment(int $userId, int $environmentId): void; } ``` --- ## 📊 개발 범위 요약 | 구분 | 항목 | 예상 기간 | 상태 | |------|------|----------|------| | Phase 1 | 기본 구조 + OpenAPI 파싱 | 3-4일 | ⬜ 대기 | | Phase 2 | 검색/필터 + 요청/응답 | 3일 | ⬜ 대기 | | Phase 3 | 즐겨찾기/템플릿/히스토리 | 3일 | ⬜ 대기 | | Phase 4 | 환경 관리 + 고급 기능 | 2-3일 | ⬜ 대기 | | Phase 5 | 테스트 + 폴리싱 | 2일 | ⬜ 대기 | | **합계** | | **13-15일** | | --- ## 🚀 Phase 1: 기본 구조 + OpenAPI 파싱 (예상 3-4일) > 📖 **설계서 참조**: 디렉토리 구조(§3), 아키텍처(§2) ### 1.1 디렉토리 구조 생성 - [ ] **Controller 생성** - [ ] `mng/app/Http/Controllers/DevTools/ApiExplorerController.php` - [ ] **Service 생성** - [ ] `mng/app/Services/ApiExplorer/OpenApiParserService.php` - [ ] `mng/app/Services/ApiExplorer/ApiRequestService.php` - [ ] `mng/app/Services/ApiExplorer/ApiExplorerService.php` - [ ] **Model 생성** - [ ] `mng/app/Models/DevTools/ApiBookmark.php` - [ ] `mng/app/Models/DevTools/ApiTemplate.php` - [ ] `mng/app/Models/DevTools/ApiHistory.php` - [ ] `mng/app/Models/DevTools/ApiEnvironment.php` - [ ] **Config 생성** - [ ] `mng/config/api-explorer.php` (설정 파일) ### 1.2 데이터베이스 마이그레이션 - [ ] **마이그레이션 파일 생성** - [ ] `create_api_bookmarks_table.php` - [ ] `create_api_templates_table.php` - [ ] `create_api_histories_table.php` - [ ] `create_api_environments_table.php` - [ ] **마이그레이션 실행** - [ ] `php artisan migrate` 실행 및 검증 ### 1.3 OpenAPI 파서 구현 - [ ] **OpenApiParserService 구현** - [ ] `parse()` - 전체 스펙 파싱 - [ ] `getEndpoints()` - 엔드포인트 목록 추출 - [ ] `getEndpoint($operationId)` - 단일 엔드포인트 조회 - [ ] `getTags()` - 태그 목록 추출 - [ ] 캐싱 로직 (파일 변경 감지) - [ ] **테스트** - [ ] api-docs.json 파싱 테스트 - [ ] 엔드포인트 추출 검증 ### 1.4 기본 UI 레이아웃 - [ ] **View 파일 생성** - [ ] `mng/resources/views/dev-tools/api-explorer/index.blade.php` - [ ] `mng/resources/views/dev-tools/api-explorer/partials/sidebar.blade.php` - [ ] `mng/resources/views/dev-tools/api-explorer/partials/request-panel.blade.php` - [ ] `mng/resources/views/dev-tools/api-explorer/partials/response-panel.blade.php` - [ ] **컴포넌트 생성** - [ ] `components/method-badge.blade.php` (HTTP 메서드 배지) - [ ] `components/endpoint-item.blade.php` (엔드포인트 목록 항목) - [ ] **3-Panel 레이아웃 구현** - [ ] 사이드바 (API 목록) - [ ] 요청 패널 - [ ] 응답 패널 - [ ] 리사이즈 가능 패널 - [ ] **라우트 설정** - [ ] `routes/web.php`에 api-explorer 라우트 그룹 추가 - [ ] 메뉴에 API Explorer 링크 추가 ### 1.5 Phase 1 완료 검증 - [ ] 기본 페이지 접근 가능 - [ ] OpenAPI 스펙에서 엔드포인트 목록 표시 - [ ] 태그별 그룹핑 동작 - [ ] 마이그레이션 정상 실행 --- ## 🔍 Phase 2: 검색/필터 + 요청/응답 (예상 3일) > 📖 **설계서 참조**: 검색 알고리즘(§7.1), 필터링(§7.2), HTMX 패턴(§8.1) ### 2.1 검색 기능 - [ ] **풀텍스트 검색 구현** - [ ] 엔드포인트 URL 검색 - [ ] summary/description 검색 - [ ] 파라미터명 검색 - [ ] operationId 검색 - [ ] **HTMX 연동** - [ ] 입력 지연 (debounce 300ms) - [ ] 부분 업데이트 (sidebar만 갱신) ### 2.2 필터 기능 - [ ] **필터 UI 구현** - [ ] HTTP 메서드 필터 (GET/POST/PUT/DELETE/PATCH) - [ ] 태그 필터 (다중 선택) - [ ] 필터 초기화 버튼 - [ ] **필터 로직** - [ ] `filter(array $filters)` 메서드 구현 - [ ] 복합 필터 (AND 조건) ### 2.3 요청 패널 - [ ] **View 구현** - [ ] `partials/request-panel.blade.php` 완성 - [ ] **입력 폼 구현** - [ ] Headers 입력 (key-value) - [ ] Path Parameters 입력 - [ ] Query Parameters 입력 - [ ] Body (JSON) 입력 - [ ] **JSON 에디터** - [ ] `components/json-editor.blade.php` - [ ] 기본 textarea + syntax highlight (선택적) - [ ] JSON 유효성 검사 ### 2.4 API 실행 (프록시) - [ ] **ApiRequestService 구현** - [ ] `execute()` 메서드 - [ ] Guzzle HTTP 클라이언트 사용 - [ ] 타임아웃 설정 (30초) - [ ] 에러 핸들링 - [ ] **Controller 메서드** - [ ] `execute(ExecuteApiRequest $request)` 구현 - [ ] **FormRequest 생성** - [ ] `ExecuteApiRequest.php` ### 2.5 응답 패널 - [ ] **View 구현** - [ ] `partials/response-panel.blade.php` 완성 - [ ] **응답 표시** - [ ] Status Code (색상 구분) - [ ] Response Headers - [ ] Response Body - [ ] **JSON 뷰어** - [ ] `components/json-viewer.blade.php` - [ ] Raw / Pretty / Tree 모드 - [ ] 복사 버튼 ### 2.6 Phase 2 완료 검증 - [ ] 검색 정상 동작 - [ ] 필터 정상 동작 - [ ] API 실행 및 응답 표시 - [ ] JSON 편집/표시 정상 동작 --- ## ⭐ Phase 3: 즐겨찾기/템플릿/히스토리 (예상 3일) > 📖 **설계서 참조**: 템플릿 시스템(§7.3), HTMX OOB(§8.2) ### 3.1 즐겨찾기 기능 - [ ] **UI 구현** - [ ] 즐겨찾기 토글 버튼 (⭐) - [ ] 즐겨찾기 목록 섹션 (사이드바 상단) - [ ] 드래그&드롭 정렬 - [ ] **CRUD 구현** - [ ] `addBookmark()` 메서드 - [ ] `removeBookmark()` 메서드 - [ ] `reorderBookmarks()` 메서드 - [ ] `getBookmarks()` 메서드 - [ ] **HTMX 연동** - [ ] 즐겨찾기 추가/제거 시 OOB 업데이트 - [ ] 정렬 변경 시 자동 저장 ### 3.2 템플릿 기능 - [ ] **UI 구현** - [ ] 템플릿 저장 모달 - [ ] 템플릿 목록 드롭다운 - [ ] 템플릿 불러오기 버튼 - [ ] **CRUD 구현** - [ ] `saveTemplate()` 메서드 - [ ] `deleteTemplate()` 메서드 - [ ] `getTemplates()` 메서드 - [ ] `templatesForEndpoint()` 메서드 - [ ] **기능 구현** - [ ] 현재 요청값을 템플릿으로 저장 - [ ] 템플릿 적용 시 폼 자동 채우기 - [ ] 공유 템플릿 (is_shared) ### 3.3 히스토리 기능 - [ ] **UI 구현** - [ ] 히스토리 서랍 (슬라이드) - [ ] 히스토리 목록 (최근 50개) - [ ] 재실행 버튼 - [ ] 전체 삭제 버튼 - [ ] **CRUD 구현** - [ ] `logRequest()` - 요청 자동 기록 - [ ] `getHistory()` - 히스토리 조회 - [ ] `clearHistory()` - 히스토리 삭제 - [ ] `replayHistory()` - 히스토리 재실행 - [ ] **자동화** - [ ] API 실행 시 자동 히스토리 저장 - [ ] 실행 시간(duration_ms) 기록 ### 3.4 Phase 3 완료 검증 - [ ] 즐겨찾기 추가/제거/정렬 동작 - [ ] 템플릿 저장/불러오기 동작 - [ ] 히스토리 자동 저장/재실행 동작 --- ## 🔧 Phase 4: 환경 관리 + 고급 기능 (예상 2-3일) > 📖 **설계서 참조**: 환경 변수(§7.4), UI 레이아웃(§5.1), 반응형(§5.3) ### 4.1 환경 관리 - [ ] **UI 구현** - [ ] 환경 선택 드롭다운 (헤더) - [ ] 환경 설정 모달 - [ ] 환경 추가/수정/삭제 - [ ] **CRUD 구현** - [ ] `getEnvironments()` 메서드 - [ ] `saveEnvironment()` 메서드 - [ ] `deleteEnvironment()` 메서드 - [ ] `setDefaultEnvironment()` 메서드 - [ ] **기본 환경 설정** - [ ] 로컬 (http://api.sam.kr) - [ ] 개발 (https://api.codebridge-x.com) ### 4.2 변수 치환 시스템 - [ ] **구현** - [ ] `{{VARIABLE_NAME}}` 패턴 인식 - [ ] 환경별 변수 저장 - [ ] 요청 시 자동 치환 - [ ] **UI** - [ ] 변수 입력 폼 (환경 설정 내) - [ ] 치환 미리보기 ### 4.3 키보드 단축키 - [ ] **구현** - [ ] `Ctrl/Cmd + Enter` - API 실행 - [ ] `Ctrl/Cmd + S` - 템플릿 저장 - [ ] `Ctrl/Cmd + K` - 검색 포커스 - [ ] `Escape` - 모달 닫기 ### 4.4 UI 폴리싱 - [ ] **반응형 최적화** - [ ] Desktop (≥1280px): 3-Panel - [ ] Tablet (768-1279px): 2-Panel + 접이식 사이드바 - [ ] Mobile (<768px): 1-Panel + 탭 전환 - [ ] **애니메이션** - [ ] 패널 전환 트랜지션 - [ ] 로딩 인디케이터 - [ ] 성공/실패 토스트 메시지 ### 4.5 Phase 4 완료 검증 - [ ] 환경 전환 정상 동작 - [ ] 변수 치환 정상 동작 - [ ] 키보드 단축키 동작 - [ ] 반응형 UI 동작 --- ## ✅ Phase 5: 테스트 + 배포 (예상 2일) > 📖 **설계서 참조**: 보안 고려사항(§9), 확장 가능성(§11) ### 5.1 기능 테스트 - [ ] **단위 테스트** - [ ] OpenApiParserService 테스트 - [ ] ApiRequestService 테스트 - [ ] ApiExplorerService 테스트 - [ ] **통합 테스트** - [ ] Controller 엔드포인트 테스트 - [ ] HTMX 부분 업데이트 테스트 ### 5.2 수동 테스트 - [ ] **시나리오 테스트** - [ ] 신규 사용자 온보딩 플로우 - [ ] 즐겨찾기 → 템플릿 → 실행 플로우 - [ ] 환경 전환 플로우 - [ ] **브라우저 호환성** - [ ] Chrome 최신 - [ ] Safari 최신 - [ ] Firefox 최신 ### 5.3 성능 최적화 - [ ] **캐싱** - [ ] OpenAPI 스펙 캐싱 - [ ] 엔드포인트 목록 캐싱 - [ ] **로딩 최적화** - [ ] 초기 로딩 시간 측정 - [ ] 필요시 지연 로딩 적용 ### 5.4 문서화 - [ ] **사용자 가이드** - [ ] 기본 사용법 - [ ] 환경 설정 방법 - [ ] 템플릿 활용법 - [ ] **개발자 가이드** - [ ] 아키텍처 설명 - [ ] 확장 방법 ### 5.5 배포 - [ ] **코드 정리** - [ ] Pint 포맷팅 - [ ] 불필요한 코드 제거 - [ ] 주석 정리 - [ ] **배포 준비** - [ ] 환경 변수 확인 - [ ] 마이그레이션 순서 확인 --- ## 📋 기획 확인 필요 항목 > ⚠️ 구현 전 결정 필요 ### 접근 권한 - [ ] API Explorer 접근 가능 사용자 범위 (개발자만? 전체?) - [ ] 환경별 접근 제한 (개발 환경에서만?) ### 보안 - [ ] API Key/Token 저장 방식 (암호화 필요?) - [ ] 히스토리에 민감 정보 마스킹 여부 - [ ] 프록시 허용 URL 화이트리스트 ### 기능 범위 - [ ] 공유 템플릿 기능 활성화 여부 - [ ] 히스토리 보관 기간 (기본 30일?) - [ ] 최대 저장 템플릿 수 제한? --- ## 📝 작업 일지 ### 2025-12-17 - [x] API Explorer 상세 설계서 작성 완료 (api-explorer-spec.md) - [x] 개발 작업 계획 초안 작성 - [x] 계획서 보완 (핵심 스키마 인라인 + 설계서 참조 링크) - DB 테이블 구조 (SQL) - 라우트 정의 (PHP) - Config 파일 - Service 메서드 시그니처 - Phase별 설계서 섹션 참조 추가 ### YYYY-MM-DD - [ ] (작업 내용 기록) --- ## ✅ 완료 기준 ### Phase 1 완료 조건 - [ ] 기본 페이지 접근 및 엔드포인트 목록 표시 - [ ] 마이그레이션 정상 실행 - [ ] 3-Panel 레이아웃 동작 ### Phase 2 완료 조건 - [ ] 검색/필터 정상 동작 - [ ] API 실행 및 응답 표시 ### Phase 3 완료 조건 - [ ] 즐겨찾기/템플릿/히스토리 CRUD 동작 ### Phase 4 완료 조건 - [ ] 환경 관리 및 변수 치환 동작 - [ ] 반응형 UI 동작 ### 전체 완료 조건 - [ ] 모든 기능 구현 완료 - [ ] 테스트 통과 - [ ] Pint 포맷팅 완료 - [ ] 문서화 완료 --- ## 🔗 관련 링크 - **상세 설계서**: [`docs/features/api-explorer-spec.md`](../features/api-explorer-spec.md) - **mng 프로젝트**: `mng/` - **기존 dev-tools**: `mng/resources/views/dev-tools/` - **OpenAPI 스펙**: `api/storage/api-docs/api-docs.json`