콘텐츠로 이동

6. 컬렉션 API#

컬렉션은 JSON 문서를 저장하는 논리적 컨테이너이다. 내부적으로 Altibase 테이블로 매핑된다.

6.1 컬렉션 유형#

컬렉션은 생성 옵션에 따라 일반 컬렉션과 공유 컬렉션으로 구분된다.

  • 일반 컬렉션: 생성한 사용자(또는 테넌트)만 접근할 수 있다.
  • 공유 컬렉션: 여러 사용자가 동일한 데이터를 공유할 수 있도록 설계된 컬렉션으로, shared=true 옵션으로 생성한다. 공유 컬렉션의 생성 및 수정, 조회, 삭제는 6.8 공유 컬렉션을 참고 한다.

6.2 컬렉션 이름 규칙#

컬렉션 생성 시 이름은 다음 규칙을 준수해야 한다:

  • 허용 문자 : 영문 대소문자, 숫자, 언더바(_)만 사용 가능하다.
  • 시작 문자 : 영문 대소문자로 시작해야 한다.
  • 길이 제한 : 최대 128자를 허용한다.
  • 고유성 : 동일한 테넌트 내에서 유일해야 한다.

Note

  • 컬렉션 데이터는 내부적으로는 clientId_collectionName 형식의 테이블이 생성되어 데이터가 저장된다.
    • 생성되는 테이블의 이름은 대소문자를 구별한다.
    • 테이블 이름의 길이가 128자를 초과할 경우, 컬렉션 생성이 실패할 수 있다.

6.3 일반 컬렉션 생성#

엔드포인트

POST /api/collections

필요 권한 : CREATE 또는 ADMIN

Note

owner 필드에 다른 사용자를 지정하는 경우, ADMIN 만 가능하다. shared 필드를 true로 설정하려면 SHARED 권한이 필요하다. 이 경우, 6.8 공유 컬렉션을 참고한다.

요청 바디

필드 타입 필수 여부 설명
name string 필수 컬렉션의 이름
owner string 선택 컬렉션의 소유자 지정 (ADMIN 전용)
options object 선택 컬렉션의 속성

options 필드

옵션 타입 설명 기본값
shared boolean 공유 컬렉션 여부 false
keyGeneration string 키 생성 방식 (UUID, CLIENT) UUID
keyColumnType string 키 컬럼 타입 (VARCHAR, CHAR, INT, INTEGER, SMALLINT, BIGINT) VARCHAR
keyColumnSize integer 키 컬럼 크기 (VARCHAR/CHAR만 해당) 40
jsonColumnType string JSON 저장 타입 (JSON, VARCHAR, CLOB) JSON

예제#

기본 컬렉션 생성#

curl -X POST http://localhost:8080/api/collections \
  -H "Authorization: Bearer ${TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{"name": "orders"}' 

클라이언트 제공 키 컬렉션#

curl -X POST http://localhost:8080/api/collections \
  -H "Authorization: Bearer ${TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "products",
    "options": {
      "keyGeneration": "CLIENT",
      "keyColumnType": "VARCHAR",
      "keyColumnSize": 50
    }
  }'

Admin이 다른 사용자의 컬렉션 생성#

curl -X POST http://localhost:8080/api/collections \
  -H "Authorization: Bearer ${ADMIN_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "logs",
    "owner": "serviceAccount",
    "options": {
      "keyGeneration": "UUID"
    }
  }'

응답 (201 Created):

{
  "name": "orders",
  "keyGeneration": "UUID",
  "keyColumnType": "VARCHAR",
  "jsonColumnType": "JSON"
}

6.4 컬렉션 목록 조회#

엔드포인트 :

GET /api/collections

필요 권한 : READ, ADMIN

예제#

curl -X GET http://localhost:8080/api/collections \
  -H "Authorization: Bearer ${TOKEN}"

응답 (200 OK):

{
  "collections": [
    {
      "name": "orders",
      "keyGeneration": "UUID",
      "keyColumnType": "VARCHAR",
      "jsonColumnType": "JSON"
    },
    {
      "name": "products",
      ...
    }
  ]
}

6.5 컬렉션 메타데이터 조회#

엔드포인트 :

GET /api/collections/{name}

필요 권한 : READ 또는 ADMIN (또는 공유 권한)

경로 파라미터 :

파라미터 타입 설명 예시
name string 컬렉션 이름 books

Caution

ownerId.collection_name 형식의 크로스 유저 메타데이터 조회는 지원하지 않는다.

예제#

# 내 컬렉션 또는 공유 컬렉션 이
curl -X GET http://localhost:8080/api/collections/books \
  -H "Authorization: Bearer ${TOKEN}"

응답 (200 OK):

{
  "name": "books",
  "keyGeneration": "UUID",
  "keyColumnType": "VARCHAR",
  "jsonColumnType": "JSON"
}

6.6 컬렉션 삭제#

Warning

컬렉션 삭제 시 해당 컬렉션의 모든 문서가 함께 삭제된다. 이 작업은 되돌릴 수 없다.

엔드포인트 :

DELETE /api/collections/{name}

필요 권한 : DROP 또는 ADMIN

예제#

curl -X DELETE http://localhost:8080/api/collections/tempData \
  -H "Authorization: Bearer ${TOKEN}"

6.7 SQL을 이용한 메타데이터 수동 삭제 (관리자 용)#

API를 통한 삭제가 불가능하거나 메타데이터 정리가 필요한 경우, SQL을 사용하여 직접 삭제할 수 있다. 이 작업은 kada_api_admin 계정으로 수행해야 한다.

1. 메타데이터 테이블에서 삭제

특정 사용자의 특정 컬렉션 메타데이터를 삭제하려면, 아래의 쿼리를 참고하여 수행한다.

-- 특정 사용자의 특정 컬렉션 메타데이터 삭제
DELETE FROM collection_metadata
WHERE collection_name = '컬렉션명'
  AND user_id = '클라이언트ID';

2. 실제 물리 테이블 삭제 (필요한 경우)

실제 테이블은 "clientId_collectionName" 형식으로 존재하기 때문에, 아래의 쿼리로 테이블을 삭제한다.

DROP TABLE "clientId_collectionName";

Warning

수동 삭제 시 API 서버의 메타데이터 캐시와 불일치가 발생할 수 있으므로, 작업 후 서버 재시작을 권장한다.

6.8 공유 컬렉션#

공유 컬렉션은 여러 사용자가 동일한 데이터를 공유할 수 있도록 설계된 컬렉션이다. 일반 컬렉션이 사용자별로 격리된 데이터를 저장하는 반면, 공유 컬렉션은 모든 사용자가 접근할 수 있는 공통 데이터를 저장한다. 공유 컬렉션은 shared=true 옵션으로 명시적으로 생성되며, 메타데이터에 is_shared='Y'로 저장된다.

주요 특징#

  • 공통 데이터셋: 여러 사용자가 동일한 컬렉션 데이터를 함께 참조한다.
  • 공유 컬렉션 전용 권한: 공유 컬렉션의 생성/문서 쓰기/삭제는 SHARED 또는 ADMIN 권한이 필요하다.
  • 조회 권한 분리: 공유 컬렉션의 문서 조회와 메타데이터 조회는 READ, WRITE, SHARED, ADMIN 중 하나로 가능하다.
  • 물리적 격리: 공유 컬렉션은 전용 테이블로 저장된다.
  • 메타데이터 표시: 시스템 메타데이터에 공유 컬렉션 여부가 기록된다.

엔드포인트 기준 권한 요약#

엔드포인트 공유 컬렉션 필요 권한
공유 컬렉션 목록 조회 READ 또는 ADMIN
공유 컬렉션 메타데이터 조회 READ, WRITE, SHARED 또는 ADMIN
공유 컬렉션의 문서 조회 READ, WRITE, SHARED 또는 ADMIN
공유 컬렉션 생성 SHARED 또는 ADMIN
공유 컬렉션 삭제 SHARED 또는 ADMIN
공유 컬렉션의 문서 삽입/수정/삭제 SHARED 또는 ADMIN

공유 컬렉션의 권한 동작#

아래 표는 REST API 엔드포인트 기준으로 권한 하나만 가진 경우의 동작을 요약한 것이다.

권한 컬렉션 생성 컬렉션 삭제 문서 쓰기 문서 읽기
READ X X X O
WRITE X X X O
CREATE X X X X
DROP X X X X
SHARED O O O O
ADMIN O O O O

제약사항#

권한 제약#

  • 공유 컬렉션의 목록 조회는 READ 또는 ADMIN 권한이 필요하다.
  • 공유 컬렉션은 ACL 부여 대상이 아니다.

이름 충돌 주의#

개인 컬렉션의 이름이 공유 컬렉션과 동일한 경우, 개인 컬렉션이 우선 조회된다. 즉 공유 컬렉션은 조회되지 않는다. 따라서 이름 충돌을 방지하기 위해 공유 컬렉션 이름에는 shared_ 접두어를 붙이는 것을 권장한다.

삭제 주의#

공유 컬렉션을 삭제하면 모든 사용자의 공통 데이터가 삭제되므로, 삭제 전에 반드시 백업 및 영향도를 확인하고 진행해야 한다.

공유 컬렉션 생성#

"shared": true 옵션이 반드시 필요하다. 공유 컬렉션의 이름에는 shared_ 접두사를 붙이는 것을 권장한다.

엔드포인트

POST /api/collections

필요 권한 : SHARED 또는 ADMIN

예제#

curl -X POST http://localhost:8080/api/collections \
  -H "Authorization: Bearer ${TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{"name": "shared_products", "options": { "shared": true, "keyGeneration": "UUID", "keyColumnType": "VARCHAR", "keyColumnSize": 40, "jsonColumnType": "JSON" }}'

결과

{"name":"shared_products","keyGeneration":"UUID","keyColumnType":"VARCHAR","jsonColumnType":"JSON","shared":true}

공유 컬렉션 목록 조회#

엔드포인트 :

GET /api/collections

필요 권한 : READ 또는 ADMIN

Note

SHARED 단독 권한만으로는 /api/collections 목록 조회를 할 수 없다.

{"error":{"code":"Forbidden.","message":"Access denied. You do not have permission to access this resource.","details":{}}}

예제#

curl -X GET http://localhost:8080/api/collections \
  -H "Authorization: Bearer ${TOKEN}"

응답 예시

{
  "collections": [
    {
      "name": "shared_products",
      "keyGeneration": "UUID",
      "keyColumnType": "VARCHAR",
      "jsonColumnType": "JSON",
      "shared": true
    }
  ]
}

공유 컬렉션에 문서 수정#

공유 컬렉션에 문서를 삽입, 수정, 삭제하는 API는 7장의 문서 API를 참고한다.

필요 권한 : SHARED 또는ADMIN

문서 삽입 예제#

curl -X POST http://localhost:8080/api/collections/shared_products/documents \
  -H "Authorization: Bearer ${TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "document": {
        "name": "MacBook Pro",
        "category": "Laptop",
        "price": 2500000    
    }
  }'

결과

{"insertedKey":"4DECC82F52D845C18E7F4D786555DAFE","keyType":"String","affectedCount":1}

공유 컬렉션 문서 조회#

공유 컬렉션의 문서를 조회하는 API는 7장의 문서 API를 참고한다.

엔드포인트 :

GET /api/collections/{name}/documents

필요 권한 : READ , WRITE , SHARED 또는ADMIN

예제#

curl -X GET http://localhost:8080/api/collections/shared_products/documents \
  -H "Authorization: Bearer ${TOKEN}"

결과

{"documents":[{"key":"4DECC82F52D845C18E7F4D786555DAFE","keyType":"String","keyFieldName":"_ID","document":{"name":"MacBook Pro","category":"Laptop","price":2500000},"created":"2026-05-27T09:19:20.702+00:00","createdBy":"userB","lastModified":"2026-05-27T09:19:20.702+00:00","lastModifiedBy":"userB"}],"totalCount":1,"hasMore":false}

공유 컬렉션 삭제#

엔드포인트 :

DELETE /api/collections/{name}

필요 권한 : SHARED 또는 ADMIN

예제#

curl -X DELETE http://localhost:8080/api/collections/shared_products \
  -H "Authorization: Bearer ${TOKEN}"

물리 테이블 구조#

명명 규칙#

컬렉션 타입 API 컬렉션명 물리 테이블명 예시
공유 컬렉션 shared_products SHARED_{collectionName} SHARED_shared_products

참고

  • 공유 컬렉션의 물리 테이블명에는 SHARED_ 접두사가 자동으로 추가된다.
  • 논리 컬렉션 이름에는 shared_ 접두사를 붙이면 가독성은 좋아지지만, 물리 테이블명에는 SHARED_가 별도로 추가되어 "SHARED_shared_products" 형태가 된다.

메타데이터 스키마#

-- collection_metadata 테이블
CREATE TABLE collection_metadata (
    user_id              VARCHAR(100),
    collection_name      VARCHAR(128),
    key_generation_type  VARCHAR(20),
    key_type_name        VARCHAR(40),
    json_column_type     VARCHAR(20),
    created_on           DATE,
    owner_id             VARCHAR(100),    -- 공유 컬렉션 소유자 (NULL or 'SHARED')
    is_shared            CHAR(1)          -- 'Y' or 'N'
);

공유 컬렉션 메타데이터 특징#

  • user_id : 'SHARED' 고정값
  • owner_id : 'SHARED' 고정값
  • is_shared : 'Y'
  • collection_name : 논리 컬렉션 이름 (예: shared_products)

공유 컬렉션 실전 예제#

아래 예제는 READ, WRITE, CREATE, DROP, SHARED 권한을 함께 가진 관리용 토큰을 사용한다.

예제 1: 국가 코드 공유 컬렉션#

  • 시나리오: 전사 공통으로 사용하는 국카 코드 데이터를 공유 컬렉션으로 관리

1단계: 공유 데이터 관리용 API Key 생성

curl -X POST http://localhost:8080/api/admin/api-keys \
 -H "Authorization: Bearer <ADMIN_JWT_TOKEN>" \
 -H "Content-Type: application/json" \
 -d '{
     "clientId": "shared_data_admin",
     "role": "READ,WRITE,CREATE,DROP,SHARED",
     "description": "공유 데이터 관리자"
     }'

2단계: JWT 토큰 발급

curl -X POST http://localhost:8080/api/auth/token \
-H "Content-Type: application/json" \
-d '{
     "clientId": "shared_data_admin",
     "apiKey": "shared_key_123456"
    }'

3단계: 공유 컬렉션 생성

curl -X POST http://localhost:8080/api/collections \
 -H "Authorization: Bearer <SHARED_MANAGER_JWT_TOKEN>" \
 -H "Content-Type: application/json" \
 -d '{
     "name": "shared_country_codes",
     "options": {
      "shared": true,
     "keyGeneration": "CLIENT",
     "keyColumnType": "VARCHAR",
     "keyColumnSize": 10
     }
    }'

4단계: 국가 코드 데이터 삽입

curl -X POST http://localhost:8080/api/collections/shared_country_codes/documents/batch \
 -H "Authorization: Bearer <SHARED_MANAGER_JWT_TOKEN>"
 -H "Content-Type: application/json" \
 -d '{
  "documents": [
    {
      "key": "KR",
      "document": {
        "name": "대한민국",
        "englishName": "Republic of Korea",
        "code2": "KR",
        "code3": "KOR",
        "numericCode": "410"
      }
    },
    {
      "key": "US",
      "document": {
        "name": "미국",
        "englishName": "United States",
        "code2": "US",
        "code3": "USA",
        "numericCode": "840"
      }
    }
  ]
}' 

5단계: 사용자가 국가 코드 조회

# READ 권한을 가진 사용자
curl -X GET http://localhost:8080/api/collections/shared_country_codes/documents \
 -H "Authorization: Bearer <READ_USER_JWT_TOKEN>" \

# 응답: 모든 국가 코드 데이터 반환

예제 2: 제품 카테고리 공유 컬렉션#

  • 시나리오: 전자상거래 애플리케이션의 제품 카테고리를 공유 컬렉션으로 관리

1단계: 공유 컬렉션 생성 (제품 카테고리)

curl -X POST http://localhost:8080/api/collections \
 -H "Authorization: Bearer <SHARED_JWT_TOKEN>" \
 -H "Content-Type: application/json"
 -d '{
  "name": "shared_categories",
  "options": {
    "shared": true,
    "keyGeneration": "UUID"
  }
}' 

2단계: 카테고리 데이터 삽입

curl -X POST http://localhost:8080/api/collections/shared_categories/documents \
 -H "Authorization: Bearer <SHARED_JWT_TOKEN>" \
 -H "Content-Type: application/json" \ 
 -d '{
  "document": {
    "name": "Electronics",
    "description": "전자제품",
    "subcategories": ["Laptop", "Smartphone", "Tablet"]
  }
}'

3단계: 사용자가 카테고리 목록 조회

# READ 권한으로 공유 카테고리 조회
curl -X GET http://localhost:8080/api/collections/shared_categories/documents \
 -H "Authorization: Bearer <READ_JWT_TOKEN>"

# 응답: 모든 카테고리 데이터

문제 해결#

공유 컬렉션 생성 실패#

  • 문제: POST /api/collections 호출 시 403 Forbidden 발생
{
  "error": "Forbidden",
  "message": "Creating shared collections requires SHARED or ADMIN authority"
}
  • 원인

  • SHARED 또는 ADMIN 권한이 없어 403 에러가 발생한 경우

  • shared:true 옵션 없이 요청을 보낸 경우

  • 해결

  • 관리용 API Key에 SHARED 권한을 부여하거나 ADMIN 권한을 사용한다.

  • 새 API Key로 JWT 토큰을 재발급한다.
  • 공유 컬렉션 생성 요청을 다시 수행한다.

공유 컬렉션 문서 삽입 실패#

  • 문제: 문서 삽입/수정/삭제 호출 시 403 또는 SecurityException 발생
{
  "error": "Security Error",
  "message": "Modifying shared collections requires SHARED or ADMIN authority"
}
  • 원인

  • SHARED 또는 ADMIN 권한이 없어 차단된 경우

  • WRITE 권한만 있고 공유 컬렉션 전용 권한이 없는 경우

  • 해결

  • SHARED 또는 ADMIN 권한 토큰을 사용한다

  • 공유 컬렉션 작업용 API Key에 SHARED 권한이 포함되어 있는지 확인한다

공유 컬렉션의 문서 읽기 실패#

  • 문제: GET /api/collections/{name} 또는 GET /api/collections/{name}/documents 호출 시 403 Forbidden 발생
  • 원인
  • READ, WRITE, SHARED, ADMIN 중 어느 권한도 없는 토큰을 사용한 경우
  • 컬렉션 이름 또는 요청 경로를 잘못 지정한 경우
  • 해결
  • 읽기용 API Key에 READ, WRITE, SHARED 중 하나 이상을 포함한다.
  • 공유 컬렉션 읽기에는 SHARED 권한으로도 접근할 수 있다는 점을 확인한다.

공유 컬렉션 조회 실패#

  • 문제: 컬렉션 목록에 공유 컬렉션이 보이지 않는 문제

  • 원인

  • 목록 조회를 위한 READ 권한이 없는 경우

  • is_shared 메타데이터가 불일치인 경우

  • 해결

  • 목록 조회용 토큰에 READ 또는 ADMIN 권한이 포함되어 있는지 확인한다.

  • 메타데이터를 조회하여 user_id가 'SHARED'인지 확인

-- 메타데이터 확인
SELECT * FROM collection_metadata WHERE is_shared = 'Y';

-- user_id가 'SHARED'인지 확인
SELECT * FROM collection_metadata WHERE user_id = 'SHARED';