필드 출력 스키마
필드 타입과 출력 형식을 이해하기 위한 API 레퍼런스
필드 출력 스키마 API
필드 출력 스키마 API는 각 필드 타입이 어떤 형식의 데이터를 반환하는지 알려줍니다. 폼 응답 데이터를 올바르게 파싱하려면 이 정보가 필요합니다.
언제 사용하나요?
폼 응답 API로 가져온 응답 데이터에는 필드 ID를 키로 한 동적 값이 들어 있습니다. 이 값이 문자열인지, 배열인지, 객체인지 알려면 필드 출력 스키마를 먼저 확인해야 합니다. 응답 파서를 만들거나 데이터를 가공할 때 이 API를 먼저 호출하세요.
참고: API 키당 시간당 6,000건의 속도 제한이 적용됩니다. 스키마는 거의 변경되지 않으므로 캐시해서 사용하는 것을 권장합니다.
개요
폼 응답의 response 객체에는 필드 ID를 키로, 필드 타입에 따른 값이 동적으로 들어갑니다. 필드 출력 스키마 API를 통해 각 필드 타입의 데이터 구조를 확인할 수 있습니다.
필드 출력 스키마 조회
필드 타입별 출력 스키마 매핑 정보를 반환합니다.
GET /open-api/v1/field-output-schemas요청
요청 예시
curl -X GET "https://api.walla.my/open-api/v1/field-output-schemas" \
-H "X-WALLA-API-KEY: your_api_key_here" \
-H "Content-Type: application/json"응답
성공 응답 (200 OK)
{
"success": true,
"data": {
"arrayTypes": {
"description": "문자열 배열을 반환하는 필드 타입",
"outputType": "array",
"fieldTypes": ["CHECKBOX", "MULTI_SELECT", "FILE_UPLOAD"],
"example": ["option1", "option2", "option3"]
},
"gridTypes": {
"description": "중첩 배열을 반환하는 필드 타입 (그리드/테이블 형식)",
"outputType": "grid",
"fieldTypes": ["GRID"],
"example": {
"rows": [
["value1", "value2"],
["value3", "value4"]
]
}
},
"objectTypes": {
"description": "구조화된 객체를 반환하는 필드 타입",
"fields": [
{
"fieldType": "ADDRESS",
"outputType": "object",
"schema": {
"type": "object",
"properties": {
"street": { "type": "string" },
"city": { "type": "string" },
"state": { "type": "string" },
"zipCode": { "type": "string" }
}
}
},
{
"fieldType": "NAME",
"outputType": "object",
"schema": {
"type": "object",
"properties": {
"firstName": { "type": "string" },
"lastName": { "type": "string" }
}
}
}
]
},
"stringTypes": {
"description": "단순 문자열을 반환하는 필드 타입",
"outputType": "string",
"fieldTypes": [
"SHORT_TEXT",
"LONG_TEXT",
"EMAIL",
"PHONE",
"NUMBER",
"DATE",
"TIME",
"URL",
"RADIO",
"DROPDOWN"
],
"example": "sample text value"
},
"nullTypes": {
"description": "입력이 필요 없는 필드 타입 (표시 전용)",
"outputType": "null",
"fieldTypes": ["HEADING", "DESCRIPTION", "DIVIDER", "IMAGE"]
}
}
}응답 필드
| 필드 | 타입 | 설명 |
|---|---|---|
success | boolean | 요청 성공 여부 |
data.arrayTypes | object | 배열을 반환하는 필드 타입에 대한 정보 |
data.arrayTypes.fieldTypes | array | 문자열 배열을 반환하는 필드 타입 목록 |
data.arrayTypes.example | array | 배열 출력 형식 예시 |
data.gridTypes | object | 그리드/테이블 필드 타입에 대한 정보 |
data.gridTypes.fieldTypes | array | 그리드 데이터를 반환하는 필드 타입 목록 |
data.gridTypes.example | object | 그리드 출력 형식 예시 |
data.objectTypes | object | 객체를 반환하는 필드 타입에 대한 정보 |
data.objectTypes.fields | array | 각 객체 필드 타입의 상세 스키마 |
data.stringTypes | object | 문자열을 반환하는 필드 타입에 대한 정보 |
data.stringTypes.fieldTypes | array | 단순 문자열을 반환하는 필드 타입 목록 |
data.stringTypes.example | string | 문자열 출력 형식 예시 |
data.nullTypes | object | 표시 전용 필드 타입에 대한 정보 |
data.nullTypes.fieldTypes | array | 값을 반환하지 않는 필드 타입 목록 |
에러 응답
- 403 Forbidden: 인증 실패
{ "error": "Authentication failed" }
필드 타입 카테고리
문자열 타입 (단순 텍스트 값)
아래 필드 타입은 단일 문자열 값을 반환합니다.
- SHORT_TEXT: 한 줄 텍스트 입력
- LONG_TEXT: 여러 줄 텍스트 입력
- EMAIL: 이메일 주소
- PHONE: 전화번호
- NUMBER: 숫자 입력
- DATE: 날짜 값
- TIME: 시간 값
- URL: 웹사이트 URL
- RADIO: 라디오 버튼에서 단일 선택
- DROPDOWN: 드롭다운 메뉴에서 단일 선택
응답 예시:
{
"field_abc123": "홍길동"
}배열 타입 (복수 값)
아래 필드 타입은 문자열 배열을 반환합니다.
- CHECKBOX: 복수 선택 체크박스
- MULTI_SELECT: 복수 선택 드롭다운
- FILE_UPLOAD: 업로드된 파일 URL 목록
응답 예시:
{
"field_xyz789": ["옵션 A", "옵션 B", "옵션 C"]
}객체 타입 (구조화된 데이터)
아래 필드 타입은 여러 속성을 포함한 객체를 반환합니다.
- ADDRESS: street, city, state, zipCode를 포함한 주소
- NAME: firstName, lastName을 포함한 이름
- PHONE_DETAILED: countryCode, number를 포함한 상세 전화번호
- DATE_RANGE: startDate, endDate를 포함한 날짜 범위
응답 예시:
{
"field_def456": {
"firstName": "길동",
"lastName": "홍"
},
"field_ghi789": {
"street": "테헤란로 123",
"city": "서울",
"state": "서울특별시",
"zipCode": "06234"
}
}그리드 타입 (테이블 데이터)
아래 필드 타입은 테이블/그리드 형태의 중첩 배열을 반환합니다.
- GRID: 행과 열이 있는 테이블
응답 예시:
{
"field_grid001": {
"rows": [
["행1 열1", "행1 열2", "행1 열3"],
["행2 열1", "행2 열2", "행2 열3"]
]
}
}Null 타입 (표시 전용)
아래 필드 타입은 입력을 받지 않으며 null을 반환합니다.
- HEADING: 섹션 제목
- DESCRIPTION: 설명 텍스트
- DIVIDER: 시각적 구분선
- IMAGE: 표시되는 이미지
응답 예시:
{
"field_heading001": null
}코드 예제
JavaScript/TypeScript
interface FieldOutputSchemas {
arrayTypes: {
description: string;
outputType: string;
fieldTypes: string[];
example: string[];
};
gridTypes: {
description: string;
outputType: string;
fieldTypes: string[];
example: object;
};
objectTypes: {
description: string;
fields: Array<{
fieldType: string;
outputType: string;
schema: object;
}>;
};
stringTypes: {
description: string;
outputType: string;
fieldTypes: string[];
example: string;
};
nullTypes: {
description: string;
outputType: string;
fieldTypes: string[];
};
}
async function getFieldOutputSchemas(): Promise<FieldOutputSchemas> {
const response = await fetch(
'https://api.walla.my/open-api/v1/field-output-schemas',
{
headers: {
'X-WALLA-API-KEY': process.env.WALLA_API_KEY!,
'Content-Type': 'application/json'
}
}
);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
return data.data;
}
// 사용 예: 필드 타입에 따라 응답 데이터 파싱
async function parseResponseValue(
fieldType: string,
value: any,
schemas: FieldOutputSchemas
): Promise<any> {
// 배열 타입인지 확인
if (schemas.arrayTypes.fieldTypes.includes(fieldType)) {
return value as string[];
}
// 문자열 타입인지 확인
if (schemas.stringTypes.fieldTypes.includes(fieldType)) {
return value as string;
}
// null 타입인지 확인
if (schemas.nullTypes.fieldTypes.includes(fieldType)) {
return null;
}
// 객체 타입인지 확인
const objectField = schemas.objectTypes.fields.find(
f => f.fieldType === fieldType
);
if (objectField) {
return value as object;
}
// 그리드 타입인지 확인
if (schemas.gridTypes.fieldTypes.includes(fieldType)) {
return value as object;
}
return value;
}
// 예제: 폼 응답 처리
const schemas = await getFieldOutputSchemas();
console.log('배열 필드 타입:', schemas.arrayTypes.fieldTypes);
console.log('문자열 필드 타입:', schemas.stringTypes.fieldTypes);Python
import requests
import os
from typing import Dict, Any, List, Union
class WallaFieldSchemas:
def __init__(self, api_key: str):
self.api_key = api_key
self.base_url = "https://api.walla.my/open-api/v1"
self.headers = {
"X-WALLA-API-KEY": api_key,
"Content-Type": "application/json"
}
self._schemas = None
def get_field_output_schemas(self) -> Dict[str, Any]:
"""필드 출력 스키마 매핑 조회"""
if self._schemas:
return self._schemas
url = f"{self.base_url}/field-output-schemas"
response = requests.get(url, headers=self.headers)
response.raise_for_status()
self._schemas = response.json()["data"]
return self._schemas
def get_output_type(self, field_type: str) -> str:
"""주어진 필드 타입의 출력 타입 조회"""
schemas = self.get_field_output_schemas()
if field_type in schemas["arrayTypes"]["fieldTypes"]:
return "array"
elif field_type in schemas["stringTypes"]["fieldTypes"]:
return "string"
elif field_type in schemas["nullTypes"]["fieldTypes"]:
return "null"
elif field_type in schemas["gridTypes"]["fieldTypes"]:
return "grid"
else:
# 객체 타입 확인
for field in schemas["objectTypes"]["fields"]:
if field["fieldType"] == field_type:
return "object"
return "unknown"
def parse_response_value(
self,
field_type: str,
value: Any
) -> Union[str, List[str], Dict, None]:
"""필드 타입에 따라 응답 값 파싱"""
output_type = self.get_output_type(field_type)
if output_type == "null":
return None
elif output_type == "array":
return value if isinstance(value, list) else []
elif output_type == "string":
return str(value) if value is not None else ""
else:
return value
# 사용 예
api = WallaFieldSchemas(os.getenv("WALLA_API_KEY"))
# 스키마 조회
schemas = api.get_field_output_schemas()
print(f"문자열 타입: {schemas['stringTypes']['fieldTypes']}")
print(f"배열 타입: {schemas['arrayTypes']['fieldTypes']}")
# 응답 값 파싱
field_type = "CHECKBOX"
value = ["옵션 A", "옵션 B"]
parsed = api.parse_response_value(field_type, value)
print(f"파싱된 값: {parsed}")사용 사례
1. 동적 폼 응답 파서
필드 출력 스키마를 활용해 범용 응답 파서를 만들 수 있습니다.
async function buildResponseParser(formId: string) {
// 필드 스키마 조회
const schemas = await getFieldOutputSchemas();
// 폼 필드를 조회하여 구조 파악
const fields = await getFormFields(formId);
// 파서 맵 생성
const parser = new Map();
fields.forEach(field => {
parser.set(field.id, {
label: field.label,
fieldType: field.fieldType,
outputType: field.outputType,
parser: (value) => parseResponseValue(field.fieldType, value, schemas)
});
});
return parser;
}
// 파서 사용
const parser = await buildResponseParser('form_abc');
const responses = await getFormResponses('form_abc');
responses.forEach(response => {
Object.entries(response.response).forEach(([fieldId, value]) => {
const fieldParser = parser.get(fieldId);
if (fieldParser) {
const parsedValue = fieldParser.parser(value);
console.log(`${fieldParser.label}: ${parsedValue}`);
}
});
});2. 응답 데이터 검증
처리 전에 응답 데이터 타입을 검증합니다.
function validateResponseData(
fieldType: string,
value: any,
schemas: FieldOutputSchemas
): boolean {
if (schemas.arrayTypes.fieldTypes.includes(fieldType)) {
return Array.isArray(value);
}
if (schemas.stringTypes.fieldTypes.includes(fieldType)) {
return typeof value === 'string';
}
if (schemas.nullTypes.fieldTypes.includes(fieldType)) {
return value === null;
}
if (schemas.gridTypes.fieldTypes.includes(fieldType)) {
return typeof value === 'object' && value !== null;
}
// 객체 타입
const objectField = schemas.objectTypes.fields.find(
f => f.fieldType === fieldType
);
if (objectField) {
return typeof value === 'object' && value !== null;
}
return true;
}3. 응답 데이터 내보내기
필드 타입에 맞게 내보내기용 데이터를 포맷팅합니다.
function formatForExport(
fieldType: string,
value: any,
schemas: FieldOutputSchemas
): string {
if (schemas.arrayTypes.fieldTypes.includes(fieldType)) {
return Array.isArray(value) ? value.join(', ') : '';
}
if (schemas.stringTypes.fieldTypes.includes(fieldType)) {
return String(value || '');
}
if (schemas.nullTypes.fieldTypes.includes(fieldType)) {
return '';
}
// 객체 타입 - JSON 문자열로 변환
if (typeof value === 'object' && value !== null) {
return JSON.stringify(value);
}
return String(value || '');
}모범 사례
-
스키마 캐싱: 필드 출력 스키마는 거의 바뀌지 않으므로, 반복 호출을 줄이기 위해 캐시하세요.
-
처리 전 검증: 응답 데이터를 처리하기 전에 타입이 예상과 맞는지 항상 확인하세요.
-
알 수 없는 타입 처리: 모르는 필드 타입이 나오면 로그를 남기되, 전체 파이프라인을 중단하지는 마세요.
-
폼 필드 API와 함께 사용: 폼 구조를 정확히 파악하려면 폼 필드 API도 함께 참조하세요.
-
타입 안전 파싱: TypeScript나 타입 힌트를 활용해 타입 안전하게 파싱하세요.