Sync

최종 수정: 2026년 6월 22일

Sync는 Space의 발행 자료를 증분(델타)으로 동기화하는 CDA 엔드포인트입니다. 발행된 Content·Media·Content Type 전체를 매번 다시 받는 대신, 클라이언트가 한 번 전체를 받아 로컬에 캐시하고, 이후로는 마지막 동기화 이후에 바뀐 것과 삭제된 것만 받아 그 캐시를 갱신합니다. 발행 자료를 통째로 들고 있어야 하는 앱(오프라인 캐시, 검색 색인, 정적 사이트 빌드 등)에서 전송량을 줄일 때 씁니다.

동기화는 두 단계로 돕니다. 먼저 초기 동기화로 전체를 받고, 응답에 담겨 오는 nextSyncUrl을 저장합니다. 다음부터는 그 URL에 들어 있는 sync-token으로 델타 동기화를 호출해 변경·삭제분만 받고, 응답이 다시 새 nextSyncUrl을 주므로 그 값을 저장해 두고 반복합니다.

동기화 흐름

  1. 초기 동기화: ?initial=true&type=All로 호출해 발행 자료 전체를 받습니다. 응답 끝에 nextSyncUrl이 담깁니다.
  2. nextSyncUrl 저장: 받은 nextSyncUrl 값을 그대로 저장합니다. 이 URL 안에 다음 호출에 쓸 sync-token이 들어 있습니다.
  3. 델타 동기화: 저장해 둔 nextSyncUrlsync-token으로 다시 호출합니다. 마지막 동기화 이후에 바뀐 것과 삭제된 것만 응답에 담겨 오고, 끝에 새 nextSyncUrl이 함께 옵니다.
  4. 반복: 받은 새 nextSyncUrl을 저장하고, 동기화가 필요할 때마다 3번을 되풀이합니다.

sync-token은 직접 만드는 값이 아니라 불투명한 커서입니다. 어떤 형식인지 해석하거나 손으로 짜 맞추지 말고, 직전 응답의 nextSyncUrl에서 받은 값을 그대로 다음 호출에 넘깁니다.

응답 구조

다음은 데모 Space의 초기 동기화(type=All) 응답입니다. items에 발행 엔티티와 삭제 마커가 섞여 담기고, 끝에 다음 델타 동기화에 쓸 nextSyncUrl이 옵니다.

{
  "sys": { "type": "PageResponse" },
  "limit": 15,
  "items": [
    {
      "sys": {
        "id": "3trmXRM3RqbgSnifyg7OGhwhlqvAvq",
        "type": "Content",
        "space": { "sys": { "id": "HnQ32YiH", "type": "Refer", "targetType": "Space" } },
        "contentType": { "sys": { "id": "3trmXRLdJF4GBlAjtcuoZ7Pnxj8dlA", "type": "Refer", "targetType": "ContentType" } },
        "createdAt": "2026-06-15T15:16:12.151Z",
        "updatedAt": "2026-06-16T14:31:20.073Z",
        "revision": 3
      },
      "fields": {
        "price": { "ko-KR": 18000 },
        "description": { "ko-KR": "이중 진공 단열로 보온·보냉이 오래갑니다. 500ml 대용량." },
        "photo": {},
        "productName": { "ko-KR": "스테인리스 텀블러 500ml" }
      }
    },
    {
      "sys": {
        "id": "3trmXRM3RqbgSnifyg7O7vFALWs1GJ",
        "type": "DeletedContent",
        "space": { "sys": { "id": "HnQ32YiH", "type": "Refer", "targetType": "Space" } },
        "contentType": { "sys": { "id": "3trmXRLdJF4GBlAjtcuoZ7Pnxj8dlA", "type": "Refer", "targetType": "ContentType" } },
        "createdAt": "2026-06-15T07:34:41.522Z",
        "updatedAt": "2026-06-15T07:41:57.198Z",
        "revision": 1
      }
    }
  ],
  "links": {},
  "nextSyncUrl": "/v1/spaces/HnQ32YiH/sync?sync-token=165rWhDiuLNoYOwjVQQAYXMA7makztXnhAV3qamYU75jFldqtvaEhMnr29PqsKTAbcoy6xs0iKpafM0KsKfZ2OHtA6pmbpx2pgx5jJ6bFzrkrBvoSvXF8tYZPkbw4X7B2EpCr95lgkQv4UJVCu1SSZIeH2ewzF"
}

주요 키:

  • sys.type: 동기화 응답을 감싸는 봉투의 종류로, 항상 "PageResponse"입니다.
  • limit: 한 번에 담긴 항목 수입니다.
  • items: 발행 엔티티와 삭제 마커가 섞여 들어가는 배열입니다. 위 예시의 첫 항목은 살아 있는 Content(본문 포함)이고, 둘째 항목은 삭제 마커(DeletedContent)로 본문 없이 sys만 담깁니다. 항목 종류는 아래 항목 종류에서 다룹니다.
  • links: 페이지 링크 객체입니다. Sync는 nextSyncUrl로 다음 페이지·다음 델타를 잇기 때문에 이 객체는 비어 있을 수 있습니다.
  • nextSyncUrl: 다음 델타 동기화에 호출할 경로입니다. 이 URL의 sync-token을 다음 호출에 그대로 씁니다.

itemsfields는 한 언어로 고르지 않은 로케일 맵 그대로입니다. 위 예시의 productName{ "ko-KR": "스테인리스 텀블러 500ml" }인 것처럼, 각 필드 값이 로케일별 값을 담은 맵으로 옵니다. CDA Content·CDA Media 조회가 locale 파라미터로 값을 단일 값으로 골라 주는 것과 달리, Sync는 한 언어로 고르지 않고 전체 맵을 그대로 내려보냅니다. 클라이언트가 이 맵을 받아 로컬에서 캐시하고 필요할 때 원하는 언어 값을 골라 씁니다. 그래서 Sync에는 locale 파라미터가 없습니다.

위 예시의 photo{}(빈 맵)인 것은 연결된 Media가 어느 로케일에도 없기 때문입니다.

항목 종류

items에는 sys.type이 서로 다른 항목이 섞여 옵니다. 크게 살아 있는 엔티티와 삭제 마커 두 갈래입니다.

sys.type본문(fields)의미
Content있음살아 있는 발행 Content. 본문 전체가 담깁니다.
Media있음살아 있는 발행 Media. 본문 전체가 담깁니다.
ContentType있음살아 있는 발행 Content Type. 본문 전체가 담깁니다.
DeletedContent없음삭제된 Content의 마커. 본문 없이 sys만 담깁니다.
DeletedMedia없음삭제된 Media의 마커. 본문 없이 sys만 담깁니다.

삭제 마커는 그 리소스가 더 이상 발행 자료에 없다는 신호입니다. 클라이언트는 마커의 sys.id를 보고 로컬 캐시에서 해당 항목을 지웁니다.

초기 동기화에서는 type 파라미터로 무엇을 받을지 고릅니다.

type받는 것
All살아 있는 Content·Media·Content Type과 삭제 마커 전부
Content살아 있는 Content(과 함께 Content Type·Media)
Media살아 있는 Media(과 함께 Content·Content Type)
Deletion삭제 마커 전부(DeletedContent·DeletedMedia)
DeletedContent삭제된 Content 마커
DeletedMedia삭제된 Media 마커

typeContentDeletedContent일 때는 content-type 파라미터로 특정 Content Type에 속한 항목만으로 한정할 수 있습니다.

API

아래 두 엔드포인트의 기준 URL은 https://cda.weegloo.com/v1이며, Authorization 헤더에 CDA를 인증하는 Bearer 토큰이 필요합니다. 둘 다 같은 경로 GET /spaces/{spaceId}/sync이며, 쿼리 파라미터로 초기 동기화와 델타 동기화를 구분합니다. Content·Media 조회와 달리 Sync에는 locale 파라미터가 없습니다. 값은 로케일 맵 그대로 옵니다.

items는 마지막 동기화 이후 변경이 없다는 뜻입니다. 이때도 새 nextSyncUrl이 오므로, 그 값을 저장해 두었다가 다음 동기화에 그대로 씁니다.

  • CDA 개요: CDA 전체와 공통 전달 동작.
  • CDA Content: 단건 조회로 한 언어 값만 골라 받은 발행 Content.
  • CDA Locale: 동기화로 받은 로케일 맵에서 값을 고를 때 쓰는 Locale 목록.
  • 다국어 (개념): 로케일 값 선택·fallback.