From 406dd34e28823fc5089e096057b7396bdbff635a Mon Sep 17 00:00:00 2001 From: Rinjae Date: Thu, 23 Jul 2026 19:30:39 +0900 Subject: [PATCH] =?UTF-8?q?-=20Mock=20Server=20URL=20=EC=B2=98=EB=A6=AC=20?= =?UTF-8?q?=EA=B0=9C=EC=84=A0:=20=EA=B2=BD=EB=A1=9C=20=EB=B6=84=EB=A6=AC(s?= =?UTF-8?q?plitFullUrl)=20=EB=A1=9C=EC=A7=81=20=EA=B5=AC=ED=98=84=20-=20?= =?UTF-8?q?=EC=9D=91=EB=8B=B5=EC=9C=A0=ED=98=95=EB=B3=84=20=ED=98=B8?= =?UTF-8?q?=EC=B6=9C=20=EC=A3=BC=EC=86=8C=20=EC=B2=98=EB=A6=AC=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EB=B3=B4=EC=99=84(GW/Mock=20=EB=B6=84=EB=A6=AC=20?= =?UTF-8?q?=EB=8C=80=EC=9D=91)=20-=20Mock=20=EC=9D=91=EB=8B=B5=20=EC=8B=9C?= =?UTF-8?q?=20=EC=A0=84=EC=B2=B4=20URL=20=EC=9C=A0=EC=A7=80=20=EB=B0=8F=20?= =?UTF-8?q?Swagger=20=EC=8A=A4=ED=8E=99=20=EB=B0=98=EC=98=81=20logic=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- WebContent/js/djb/apispec/app.js | 43 ++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/WebContent/js/djb/apispec/app.js b/WebContent/js/djb/apispec/app.js index 5789493..4d2ba55 100644 --- a/WebContent/js/djb/apispec/app.js +++ b/WebContent/js/djb/apispec/app.js @@ -189,15 +189,23 @@ // 경로(op.path.value)에는 어댑터경로가 이미 baking 됨(백엔드 applyAutoRules). 서버에는 응답유형별 호스트만 붙인다. // - gw : djb.gateway.base-url (PortalProperty) → [gw호스트 + 어댑터경로 + 경로] - // - mock : Mock Server URL → [mock호스트 + 어댑터경로 + 경로] + // - mock : Mock Server URL(전체 URL) → [mock URL 그대로] (어댑터/오퍼레이션 경로 미부착) // - 그 외 : 호스트 없음 → [어댑터경로 + 경로] var _rt = (d.portal && d.portal.responseType) || 'sample'; var _host; - if (_rt === 'gw') _host = (window.DJB_CTX && window.DJB_CTX.gwAddress) || 'http://127.0.0.1:39310'; - else if (_rt === 'mock') _host = (d.portal && d.portal.mockUrl) || ''; - else _host = ''; + var _pathKey = op.path.value; + if (_rt === 'gw') { + _host = (window.DJB_CTX && window.DJB_CTX.gwAddress) || 'http://127.0.0.1:39310'; + } else if (_rt === 'mock') { + // Mock 은 전체 호출 URL. origin=서버, pathname(+query)=경로로 분해해 경로가 뒤에 덧붙지 않도록 한다. + var _mk = splitFullUrl((d.portal && d.portal.mockUrl) || ''); + _host = _mk.origin; + _pathKey = _mk.path; + } else { + _host = ''; + } if (_host) spec.servers = [{ url: _host }]; - spec.paths[op.path.value] = { [op.method.value.toLowerCase()]: operation }; + spec.paths[_pathKey] = { [op.method.value.toLowerCase()]: operation }; // 보안 스킴 d.securitySchemes.forEach(s => { @@ -946,14 +954,27 @@ } } - // 응답유형별 실제 호출 주소. 경로(op.path.value)에 어댑터경로가 이미 포함, 호스트만 응답유형별로 앞에 붙임. + // 전체 URL → { origin, path }. Mock Server URL 을 서버+경로로 분해(경로를 별도로 덧붙이지 않기 위함). + function splitFullUrl(u) { + u = (u || '').trim(); + if (!u) return { origin: '', path: '/' }; + try { + var parsed = new URL(u); + var path = (parsed.pathname || '/') + (parsed.search || ''); + if (!path || path.charAt(0) !== '/') path = '/' + path; + return { origin: parsed.origin, path: path }; + } catch (e) { + // 스킴 누락/파싱 실패 → 통째 origin 취급, path 는 '/' + return { origin: u.replace(/\/+$/, ''), path: '/' }; + } + } + + // 응답유형별 실제 호출 주소. gw 는 [호스트 + 경로], mock 은 입력한 전체 URL 그대로(경로 미부착). function resolvedCallUrl() { var d = state.data; var rt = (d.portal && d.portal.responseType) || 'sample'; - var host; - if (rt === 'gw') host = (window.DJB_CTX && window.DJB_CTX.gwAddress) || 'http://127.0.0.1:39310'; - else if (rt === 'mock') host = (d.portal && d.portal.mockUrl) || ''; - else host = ''; + if (rt === 'mock') return (((d.portal && d.portal.mockUrl) || '').trim()) || '(주소 없음)'; + var host = (rt === 'gw') ? ((window.DJB_CTX && window.DJB_CTX.gwAddress) || 'http://127.0.0.1:39310') : ''; var path = (d.operation && d.operation.path && d.operation.path.value) || ''; if (!host) return path || '(주소 없음)'; return host.replace(/\/+$/, '') + (path.charAt(0) === '/' ? path : '/' + path); @@ -1012,7 +1033,7 @@ : `
실제 호출 주소: ${escapeHtml(resolvedCallUrl())}
`) + (rt === 'gw' ? `
GW 주소는 포탈 설정(PTL_PROPERTY, 그룹 Portal)의 djb.gateway.base-url 값을 사용합니다.
` : '') + '') + - (rt === 'mock' ? fieldRow('Mock Server URL', input(p.mockUrl || '', 'data-portal="mockUrl"', { placeholder: 'https://mock.example.com' }), { hint: 'Mock 응답을 제공할 서버의 기본 URL. 응답 유형이 Mock 일 때 개발자포탈이 이 주소로 요청을 전달하고, Swagger 스펙의 서버 주소로도 사용됩니다.' }) : '') + (rt === 'mock' ? fieldRow('Mock Server URL', input(p.mockUrl || '', 'data-portal="mockUrl"', { placeholder: 'https://mock.example.com/api/v1/foo' }), { hint: 'Mock 응답을 제공할 전체 호출 URL(경로 포함). 응답 유형이 Mock 일 때 이 주소로 그대로 호출하며, 어댑터/오퍼레이션 경로를 뒤에 덧붙이지 않습니다.' }) : '') ) + card( sectionTitle('설명 (API 소개 페이지)', 'API 소개 페이지에만 표시됩니다. OpenAPI 스펙 파일에는 포함되지 않습니다.') +