Files
2026-01-19 09:31:33 +09:00

541 lines
15 KiB
Markdown

# OBP API 사용자 가이드
## 개요
OBP (OpenBanking Platform) API는 API Gateway의 메트릭 데이터와 API 정보를 JSON 형식으로 제공하는 REST 기반 API입니다.
**API 기본 URL**: `/monitoring/api/`
**지원 형식**: JSON
## 인증 및 권한
### providerCode 파라미터
OBP API는 모든 요청에서 `providerCode` 파라미터로 권한을 검증합니다.
- **허용 값**: `KJB` (대소문자 무시: `kjb`, `Kjb` 등 모두 가능)
- **검증**: 요청 시 providerCode가 반드시 포함되어야 합니다 (필수 파라미터)
- **검증 실패**: 유효하지 않은 providerCode는 `BizException` 에러 발생
**예시**:
```
GET /api/apis/KJB
GET /api/apis/000008-01/KJB
GET /api/metrics/afterTimeslice/20251202030000/KJB
```
## API 엔드포인트
### 1. API 전체 목록 조회
#### 요청
```http
GET /api/apis/{providerCode}
```
**경로 파라미터**:
- `providerCode` (필수): Provider 코드 (KJB만 허용, 대소문자 무시)
**쿼리 파라미터**:
- `pretty` (선택): `true`면 JSON을 들여쓰기 형식으로 반환
**예시**:
```bash
curl "http://localhost:8080/monitoring/api/apis/KJB"
curl "http://localhost:8080/monitoring/api/apis/kjb?pretty=true"
```
#### 응답
```json
[
{
"interfaceId": "UAGFF00001UIE",
"interfaceName": "고객 조회 API",
"status": "1",
"description": "고객 기본정보 조회"
},
{
"interfaceId": "UAGFF00002UIE",
"interfaceName": "거래 조회 API",
"status": "1",
"description": "거래 내역 조회"
}
]
```
**응답 필드**:
- `interfaceId` (string): 인터페이스 ID
- `interfaceName` (string): 인터페이스 명
- `status` (string): 상태 (1=활성)
- `description` (string): 설명
**HTTP 상태 코드**:
- `200 OK`: 조회 성공
- `400 Bad Request`: 유효하지 않은 providerCode
```json
{
"errorCode": "BIZ_EXCEPTION",
"errorMessage": "Invalid providerCode. Expected 'KJB' (case-insensitive), got: INVALID"
}
```
- `500 Internal Server Error`: 서버 오류
---
### 2. API 목록 조회 (기관별)
#### 요청
```http
GET /api/apis/{orgCode}/{providerCode}
```
**경로 파라미터**:
- `orgCode` (필수): 기관코드 (OBP 파트너코드)
- `providerCode` (필수): Provider 코드 (KJB만 허용, 대소문자 무시)
**쿼리 파라미터**:
- `pretty` (선택): `true`면 JSON을 들여쓰기 형식으로 반환
**예시**:
```bash
curl "http://localhost:8080/monitoring/api/apis/000008-01/KJB"
curl "http://localhost:8080/monitoring/api/apis/000008-01/kjb?pretty=true"
```
#### 응답
특정 기관이 사용하는 API 목록 (응답 형식은 엔드포인트 1과 동일)
**주의사항**:
- 기관이 존재하지 않으면 빈 배열(`[]`)이 반환됩니다
- 해당 기관의 활성 앱(appstatus='1')이 사용하는 API만 반환됩니다
**HTTP 상태 코드**:
- `200 OK`: 조회 성공 (데이터 있음 또는 없음)
- `400 Bad Request`: 유효하지 않은 providerCode 또는 orgCode
- `500 Internal Server Error`: 서버 오류
---
### 3. GwMetric 데이터 조회 (시간대 이후)
#### 요청
```http
GET /api/metrics/afterTimeslice/{timeslice}/{providerCode}
```
**경로 파라미터**:
- `timeslice` (필수): 조회 시작 시간대 (형식: `yyyyMMddHHmmss`)
- 예: `20251202030000` (2025-12-02 03:00:00)
- 분/초는 자동으로 정각(00:00)으로 처리됩니다
- `providerCode` (필수): Provider 코드 (KJB만 허용, 대소문자 무시)
**쿼리 파라미터**:
- `pretty` (선택): `true`면 JSON을 들여쓰기 형식으로 반환
**예시**:
```bash
curl "http://localhost:8080/monitoring/api/metrics/afterTimeslice/20251202030000/KJB"
curl "http://localhost:8080/monitoring/api/metrics/afterTimeslice/20251202030000/kjb?pretty=true"
```
#### 응답
```json
[
{
"timeslice": "2025-12-02 03:00:00",
"transactionCount": 1250,
"successCount": 1230,
"failureCount": 20,
"averageResponseTime": 145
},
{
"timeslice": "2025-12-02 04:00:00",
"transactionCount": 1380,
"successCount": 1360,
"failureCount": 20,
"averageResponseTime": 152
}
]
```
**응답 필드**:
- `timeslice` (string): 시간대 (형식: `yyyy-MM-dd HH:00:00`)
- `transactionCount` (number): 총 거래 건수
- `successCount` (number): 성공 건수
- `failureCount` (number): 실패 건수
- `averageResponseTime` (number): 평균 응답 시간 (ms)
**HTTP 상태 코드**:
- `200 OK`: 조회 성공
- `400 Bad Request`: 유효하지 않은 timeslice 또는 providerCode
```json
{
"errorCode": "BIZ_EXCEPTION",
"errorMessage": "Invalid timeslice format. Expected 'yyyyMMddHHmmss', got: 2025-12-02_03:00:00"
}
```
- `500 Internal Server Error`: 서버 오류
---
## 예제 코드
### JavaScript (fetch API)
```javascript
// 1. API 전체 목록 조회
async function getAllApis() {
try {
const response = await fetch(
'http://localhost:8080/monitoring/api/apis/KJB?pretty=true'
);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
console.log('All APIs:', data);
return data;
} catch (error) {
console.error('Error fetching APIs:', error);
}
}
// 2. 기관별 API 목록 조회
async function getApisByPartner(partnerCode) {
try {
const response = await fetch(
`http://localhost:8080/monitoring/api/apis/${partnerCode}/KJB?pretty=true`
);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
console.log(`APIs for ${partnerCode}:`, data);
return data;
} catch (error) {
console.error('Error fetching APIs:', error);
}
}
// 3. GwMetric 데이터 조회
async function getMetricsAfterTimeslice(timeslice) {
try {
const response = await fetch(
`http://localhost:8080/monitoring/api/metrics/afterTimeslice/${timeslice}/KJB?pretty=true`
);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
console.log(`Metrics after ${timeslice}:`, data);
return data;
} catch (error) {
console.error('Error fetching metrics:', error);
}
}
// 사용 예
getAllApis();
getApisByPartner('000008-01');
getMetricsAfterTimeslice('20251202030000');
```
### JavaScript (axios)
```javascript
const axios = require('axios');
const BASE_URL = 'http://localhost:8080/monitoring/api';
// 1. API 전체 목록 조회
async function getAllApis() {
try {
const response = await axios.get(`${BASE_URL}/apis/KJB`, {
params: { pretty: true }
});
console.log('All APIs:', response.data);
return response.data;
} catch (error) {
console.error('Error fetching APIs:', error.response?.data || error.message);
}
}
// 2. 기관별 API 목록 조회
async function getApisByPartner(partnerCode) {
try {
const response = await axios.get(`${BASE_URL}/apis/${partnerCode}/KJB`, {
params: { pretty: true }
});
console.log(`APIs for ${partnerCode}:`, response.data);
return response.data;
} catch (error) {
console.error('Error fetching APIs:', error.response?.data || error.message);
}
}
// 3. GwMetric 데이터 조회
async function getMetricsAfterTimeslice(timeslice) {
try {
const response = await axios.get(`${BASE_URL}/metrics/afterTimeslice/${timeslice}/KJB`, {
params: { pretty: true }
});
console.log(`Metrics after ${timeslice}:`, response.data);
return response.data;
} catch (error) {
console.error('Error fetching metrics:', error.response?.data || error.message);
}
}
```
### Java (RestTemplate)
```java
import org.springframework.web.client.RestTemplate;
import java.util.List;
import java.util.Map;
public class ObpApiClient {
private final RestTemplate restTemplate = new RestTemplate();
private static final String BASE_URL = "http://localhost:8080/monitoring/api";
// 1. API 전체 목록 조회
public List<Map> getAllApis() {
String url = BASE_URL + "/apis/KJB?pretty=true";
return restTemplate.getForObject(url, List.class);
}
// 2. 기관별 API 목록 조회
public List<Map> getApisByPartner(String partnerCode) {
String url = BASE_URL + "/apis/" + partnerCode + "/KJB?pretty=true";
return restTemplate.getForObject(url, List.class);
}
// 3. GwMetric 데이터 조회
public List<Map> getMetricsAfterTimeslice(String timeslice) {
String url = BASE_URL + "/metrics/afterTimeslice/" + timeslice + "/KJB?pretty=true";
return restTemplate.getForObject(url, List.class);
}
// 사용 예
public static void main(String[] args) {
ObpApiClient client = new ObpApiClient();
// 1. API 목록 조회
List<Map> apis = client.getAllApis();
System.out.println("All APIs: " + apis);
// 2. 기관별 API 조회
List<Map> partnerApis = client.getApisByPartner("000008-01");
System.out.println("Partner APIs: " + partnerApis);
// 3. 메트릭 조회
List<Map> metrics = client.getMetricsAfterTimeslice("20251202030000");
System.out.println("Metrics: " + metrics);
}
}
```
### cURL
```bash
# 1. API 전체 목록 조회
curl "http://localhost:8080/monitoring/api/apis/KJB?pretty=true"
curl "http://localhost:8080/monitoring/api/apis/kjb"
# 2. 기관별 API 목록 조회
curl "http://localhost:8080/monitoring/api/apis/000008-01/KJB?pretty=true"
curl "http://localhost:8080/monitoring/api/apis/000008-01/kjb"
# 3. GwMetric 데이터 조회
curl "http://localhost:8080/monitoring/api/metrics/afterTimeslice/20251202030000/KJB?pretty=true"
curl "http://localhost:8080/monitoring/api/metrics/afterTimeslice/20251202030000/kjb"
```
---
## 에러 처리
### 에러 응답 형식
```json
{
"errorCode": "BIZ_EXCEPTION",
"errorMessage": "Invalid providerCode. Expected 'KJB' (case-insensitive), got: INVALID"
}
```
### 주요 에러 코드
| 에러 코드 | HTTP 상태 | 원인 | 해결 방법 |
|---------|---------|------|---------|
| `BIZ_EXCEPTION` | 400 | 유효하지 않은 providerCode | providerCode를 "KJB" (대소문자 무시)로 설정 |
| `BIZ_EXCEPTION` | 400 | 유효하지 않은 timeslice 형식 | timeslice를 `yyyyMMddHHmmss` 형식으로 변경 |
| `INTERNAL_ERROR` | 500 | 서버 오류 | 시스템 관리자에게 문의 |
---
## 마이그레이션 가이드
### 레거시 엔드포인트에서 마이그레이션
레거시 `/kjb/` 경로 엔드포인트는 앞으로 지원이 중단될 예정입니다. 새로운 `/api/` 경로로 마이그레이션하세요.
#### ObpApiController
**기존 엔드포인트** → **새 엔드포인트**
```
GET /kjb/apis.json
GET /api/apis/{providerCode}
```
```
GET /kjb/{orgCode}/apis.json
GET /api/apis/{orgCode}/{providerCode}
```
**예시**:
기존:
```bash
curl "http://localhost:8080/monitoring/kjb/apis.json"
curl "http://localhost:8080/monitoring/kjb/000008-01/apis.json"
```
새로운:
```bash
curl "http://localhost:8080/monitoring/api/apis/KJB"
curl "http://localhost:8080/monitoring/api/apis/000008-01/KJB"
```
#### ObpGwMetricController
**기존 엔드포인트** → **새 엔드포인트**
```
GET /kjb/gw-metrics/{datetime}.json
GET /api/metrics/afterTimeslice/{timeslice}/{providerCode}
```
```
GET /kjb/gw-metrics/after-timeslice/{datetime}.json
GET /api/metrics/afterTimeslice/{timeslice}/{providerCode}
```
**datetime 형식 변환**:
| 기존 형식 | 새 형식 |
|---------|--------|
| `yyyy-MM-dd_HH:mm:ss` | `yyyyMMddHHmmss` |
| `2025-12-02_03:00:00` | `20251202030000` |
| `2026-01-18_15:30:45` | `20260118153045` |
**예시**:
기존:
```bash
curl "http://localhost:8080/monitoring/kjb/gw-metrics/2025-12-02_03:00:00.json"
curl "http://localhost:8080/monitoring/kjb/gw-metrics/after-timeslice/2025-12-02_03:00:00.json"
```
새로운:
```bash
curl "http://localhost:8080/monitoring/api/metrics/afterTimeslice/20251202030000/KJB"
```
---
## FAQ
### Q1: providerCode는 무엇인가요?
**A**: providerCode는 API 접근 권한을 검증하는 필수 파라미터입니다. 현재 OBP API는 "KJB" (광주은행)만 허용합니다.
### Q2: providerCode 대소문자를 혼합해도 되나요?
**A**: 네, 가능합니다. `KJB`, `kjb`, `Kjb`, `kJB` 등 모두 허용됩니다.
### Q3: timeslice 형식은 어떻게 변환하나요?
**A**: `yyyy-MM-dd_HH:mm:ss` → `yyyyMMddHHmmss` 형식으로 변환합니다.
- 예: `2025-12-02_03:30:45` → `20251202033045`
- 분과 초도 포함되어 있으므로 정확하게 입력하세요.
### Q4: timeslice에 분/초를 입력해도 되나요?
**A**: 네, 입력 가능합니다. 하지만 시스템은 자동으로 정각(00분, 00초)으로 처리합니다.
- 입력: `20251202033045` (03:30:45)
- 처리: `2025-12-02 03:00:00`
### Q5: 기관이 없으면 어떻게 되나요?
**A**: 기관이 존재하지 않으면 빈 배열(`[]`)이 반환됩니다. 에러가 발생하지 않습니다.
### Q6: 응답 형식을 변경할 수 있나요?
**A**: 현재 JSON 형식만 지원합니다. 다른 형식이 필요하면 시스템 관리자에게 문의하세요.
### Q7: pretty 파라미터를 사용하지 않으면 어떻게 되나요?
**A**: pretty 파라미터를 생략하면 compact한 형식(들여쓰기 없음)으로 반환됩니다.
- `?pretty=true`: 들여쓰기 적용 (가독성 좋음, 용량 큼)
- 파라미터 없음: compact 형식 (가독성 낮음, 용량 작음)
### Q8: API 응답 시간은 어느 정도인가요?
**A**: 응답 로그에 `elapsed` 정보가 포함됩니다. 로그에서도 확인할 수 있습니다.
### Q9: providerCode를 생략할 수 있나요?
**A**: 아니요, providerCode는 필수 파라미터입니다. 반드시 URL 경로에 포함되어야 합니다.
---
## 최신 변경사항
### v2.0 (2025-01-19)
- **새로운 `/api/*` 경로**: RESTful 규칙 준수
- `/api/apis/{providerCode}` - 전체 API 목록
- `/api/apis/{orgCode}/{providerCode}` - 기관별 API 목록
- `/api/metrics/afterTimeslice/{timeslice}/{providerCode}` - GwMetric 데이터
- **Path 변수 기반**: 모든 providerCode/timeslice를 경로 변수로 변경
- **providerCode 검증**: 모든 엔드포인트에서 필수 검증 (KJB 대소문자 무시)
- **timeslice 형식**: `yyyy-MM-dd_HH:mm:ss` → `yyyyMMddHHmmss`
- **레거시 엔드포인트 유지**: `/kjb/*` 경로는 당분간 지원 (Deprecated)
**마이그레이션 권장**: 가능한 한 빨리 새로운 경로로 업데이트하세요.
---
## 지원
문제가 발생하거나 추가 정보가 필요한 경우:
1. **기술 문의**: API 개발팀 (api-support@example.com)
2. **버그 신고**: GitHub Issues
3. **기능 요청**: 관리자에게 연락
---
**마지막 업데이트**: 2025-01-19
**API 버전**: 2.0