OneAsset Developers

OneAsset Developer Guide

실제 백엔드 코드 기준으로 Dashboard API, Developer API, 업로드 요청, 상태 조회, 삭제, 헬스체크 방법을 정리합니다.

목차

  1. 01인증면 구분
  2. 02Base URL과 환경변수
  3. 03API Key 발급 흐름
  4. 04Asset 업로드 요청
  5. 05업로드 처리 흐름
  6. 06Asset key 규칙
  7. 07응답 필드와 재접근 URL
  8. 08상태 조회와 status 의미
  9. 09Asset 목록/상세/삭제
  10. 10헬스체크
  11. 11에러 처리

1. 인증면 구분

Dashboard API

브라우저 대시보드가 프로젝트, API Key, Asset 목록을 관리할 때 사용합니다. Cognito Hosted UI 로그인 후 받은 JWT를 Bearer token으로 보냅니다.

Authorization: Bearer {cognito_jwt}

Developer API

외부 백엔드/서버 애플리케이션이 파일을 업로드하거나 조회할 때 사용합니다. raw API Key는 Dashboard 브라우저 요청에 사용하지 않습니다.

X-OneAsset-Api-Key: {raw_api_key}

2. Base URL과 환경변수

프론트는 `NEXT_PUBLIC_API_BASE_URL`을 기준으로 Dashboard API를 호출합니다. Developer API를 호출하는 외부 서버도 같은 백엔드 origin을 사용하되, 인증 헤더만 `X-OneAsset-Api-Key`로 바꿉니다.

Surface환경변수설명
FrontendNEXT_PUBLIC_API_BASE_URL대시보드가 호출할 백엔드 origin. 로컬 기본값은 http://localhost:8080.
BackendAPP_PORTSpring Boot 서버 포트. 로컬 Docker 실행 기준 8080.
BackendONEASSET_DELIVERY_BASE_URLdeliveryUrl 계산에 쓰는 CDN/base URL. 비어 있으면 응답 deliveryUrl은 null.

3. API Key 발급 흐름

  1. 01Dashboard에서 Google/Cognito로 로그인합니다.
  2. 02POST /api/projects로 프로젝트를 생성합니다.
  3. 03POST /api/projects/{projectId}/api-keys로 API Key를 발급합니다.
  4. 04응답의 apiKey raw value는 발급 직후 한 번만 복사합니다.
  5. 05이후 목록에서는 raw key가 아니라 prefix/status만 확인합니다.

4. Asset 업로드 요청

실제 컨트롤러는 `POST /v1/assets`에서 multipart/form-data를 받습니다. `file`은 필수이고, `key`, `fileName`은 선택입니다.

curl -X POST https://api.oneasset.example/v1/assets \
  -H "X-OneAsset-Api-Key: oa_live_..." \
  -F "file=@hero.png" \
  -F "key=products/main/hero.png" \
  -F "fileName=hero.png"
FieldRequired설명
fileY업로드할 원본 파일. multipart part 이름은 file.
keyN사용자/앱이 다시 조회할 논리 경로. 없으면 서버가 assets/{uuid}.{ext} 형태로 생성.
fileNameN표시용 원본 파일명. 없으면 multipart original filename 사용. 현재 백엔드 파라미터명은 name이 아니라 fileName.

Node.js 서버 예시

raw API Key는 브라우저에 노출하지 않고 서버 환경변수로 관리합니다. 아래 예시는 외부 백엔드에서 OneAsset Developer API로 전달하는 형태입니다.

const form = new FormData();
form.append("file", fileBlob, "hero.png");
form.append("key", "products/main/hero.png");
form.append("fileName", "hero.png");

const response = await fetch(`${process.env.ONEASSET_API_URL}/v1/assets`, {
  method: "POST",
  headers: {
    "X-OneAsset-Api-Key": process.env.ONEASSET_API_KEY,
  },
  body: form,
});

const result = await response.json();
const asset = result.data;

// 실제 이미지 재접근에는 asset.deliveryUrl을 사용합니다.
console.log(asset.deliveryUrl);

5. 업로드 처리 흐름

Step무엇을 하나설명
1외부 서버가 raw API Key를 준비합니다.Dashboard에서 발급 직후 한 번만 보이는 `oa_live_...` 값을 서버 환경변수에 저장합니다.
2multipart/form-data로 파일을 보냅니다.`file`은 필수입니다. `key`는 사용자가 다시 찾을 논리 경로이고, `fileName`은 표시용 이름입니다.
3백엔드는 S3 storageKey를 만듭니다.`projects/{projectId}/{key}` 형태로 저장합니다. 사용자는 이 값을 직접 만들 필요가 없습니다.
4응답의 deliveryUrl을 저장하거나 노출합니다.이미지 재접근, img src, CDN 전달에는 `deliveryUrl`을 씁니다. key/storageKey는 식별과 조회용입니다.
5PROCESSING이면 상세 API를 다시 조회합니다.`GET /v1/assets?key={key}`로 status가 READY가 될 때까지 polling합니다.

6. Asset key 규칙

허용되는 형태

  • `users/123/profile.png`
  • `products/iphone/main.png`
  • `assets/manual-upload.png`

정규화/거부 규칙

  • 앞의 `/`는 제거됩니다.
  • `\`는 `/`로 바뀝니다.
  • 빈 segment, `.`, `..`는 `COMMON_INVALID_INPUT_400`입니다.
  • `key`를 생략하면 서버가 `assets/{uuid}.{ext}` 논리 key를 생성합니다.

7. 응답 필드와 재접근 URL

응답의 `key`는 사용자 논리 경로이고, `storageKey`는 S3 내부 경로입니다. 재접근 URL은 `deliveryUrl`을 사용합니다. 백엔드 환경변수 `ONEASSET_DELIVERY_BASE_URL`이 비어 있으면 `deliveryUrl`은 null입니다.

{
  "success": true,
  "data": {
    "assetId": "f88dcad8-020c-4ed5-bda9-6c078e52a819",
    "key": "products/main/hero.png",
    "storageKey": "projects/{projectId}/products/main/hero.png",
    "originalFileName": "hero.png",
    "contentType": "image/png",
    "sizeBytes": 125432,
    "status": "PROCESSING",
    "deliveryUrl": "https://cdn.example.com/projects/{projectId}/products/main/hero.png",
    "createdAt": "2026-07-21T17:10:00"
  },
  "error": null
}
Field설명
assetIdAsset UUID. Dashboard 내부 링크와 식별에 사용.
key사용자가 다루는 논리 경로. 예: users/123/profile.png
storageKeyS3 내부 저장 경로. 예: projects/{projectId}/users/123/profile.png
originalFileName표시용 원본 파일명. 경로가 들어오면 마지막 파일명만 사용.
contentType업로드 파일 MIME type.
sizeBytes원본 파일 크기. 0 이하이면 ASSET_INVALID_SIZE_400.
statusUPLOADED, PROCESSING, READY, FAILED 중 하나.
deliveryUrlONEASSET_DELIVERY_BASE_URL이 설정되어 있으면 storageKey를 붙여 계산한 재접근 URL. 설정이 없으면 null.
createdAtAsset metadata 생성 시각.

어떤 값을 저장해야 하나

  • `key`: 이후 상세 조회, 삭제, 트리 렌더링에 사용합니다.
  • `deliveryUrl`: 실제 이미지 접근 URL로 사용합니다.
  • `storageKey`: 운영/디버깅용 내부 저장 경로로만 취급합니다.
  • `deliveryUrl`이 null이면 백엔드 CDN/base URL 설정이 비어 있는 상태입니다. 이 경우 프론트는 URL 복사 버튼을 숨깁니다.

8. 상태 조회와 status 의미

현재 실제 상태 조회는 별도 `/status` path가 아니라`GET /v1/assets?key={key}`입니다. 같은 endpoint가 상세 metadata와 status를 함께 반환합니다.

curl "https://api.oneasset.example/v1/assets?key=products/main/hero.png" \
  -H "X-OneAsset-Api-Key: oa_live_..."
Status의미클라이언트 처리
UPLOADED원본 업로드와 metadata 생성이 완료된 도메인 초기 상태입니다.현재 register 흐름에서는 곧바로 PROCESSING으로 전환되어 응답에서 보기 어려울 수 있습니다.
PROCESSING원본이 저장되고 처리 큐에 등록된 상태입니다.GET /v1/assets?key={key}를 주기적으로 재조회합니다. UI에서는 처리 중으로 표시합니다.
READYLambda callback으로 변환본 metadata가 등록되고 Asset이 준비된 상태입니다.deliveryUrl을 사용할 수 있는 상태로 안내하고 URL 복사 액션을 제공합니다.
FAILED처리 실패 상태입니다.사용자에게 실패를 명확히 보여주고 파일/contentType 확인 후 재업로드를 안내합니다. 현재 확인한 컨트롤러에는 실패 callback API가 아직 노출되어 있지 않습니다.

polling 예시

업로드 응답이 `PROCESSING`이면 같은 `key`로 상세 API를 재조회합니다. `READY`가 되면 `deliveryUrl`을 화면에 보여주고, `FAILED`면 재업로드 안내를 표시합니다.

async function waitUntilReady(key) {
  for (let attempt = 0; attempt < 10; attempt += 1) {
    const res = await fetch(
      `${process.env.ONEASSET_API_URL}/v1/assets?key=${encodeURIComponent(key)}`,
      { headers: { "X-OneAsset-Api-Key": process.env.ONEASSET_API_KEY } },
    );
    const { data } = await res.json();

    if (data.status === "READY") return data.deliveryUrl;
    if (data.status === "FAILED") throw new Error("Asset processing failed.");

    await new Promise((resolve) => setTimeout(resolve, 1500));
  }

  throw new Error("Asset is still processing.");
}

9. Asset 목록, 상세, 삭제

목록

API Key가 속한 프로젝트의 active asset 목록을 반환합니다.

GET /v1/assets
X-OneAsset-Api-Key: oa_live_...

상세/상태

논리 key로 asset metadata, status, deliveryUrl을 조회합니다.

GET /v1/assets?key=products/main/hero.png
X-OneAsset-Api-Key: oa_live_...

삭제

S3 object 삭제 후 DB row는 soft delete 처리됩니다. CloudFront 캐시는 잠시 남을 수 있습니다.

DELETE /v1/assets?key=products/main/hero.png
X-OneAsset-Api-Key: oa_live_...

목록 응답으로 트리 만들기

백엔드는 folder/tree 구조를 만들지 않고 flat list를 반환합니다. 프론트는 응답의 `key`를 `/` 기준으로 split해서 Asset Browser tree를 렌더링합니다.

[
  { "key": "users/123/profile.png", "status": "READY" },
  { "key": "users/123/banner.png", "status": "READY" },
  { "key": "products/iphone/main.png", "status": "PROCESSING" }
]

users
  123
    profile.png
    banner.png
products
  iphone
    main.png

10. 헬스체크

백엔드 SecurityConfig 기준 `/actuator/health`는 인증 없이 허용됩니다. 배포/모니터링에서는 이 endpoint로 API 프로세스와 actuator 상태를 확인합니다.

curl https://api.oneasset.example/actuator/health

// typical Spring Boot response
{
  "status": "UP"
        }

11. Dashboard API 엔드포인트

MethodPath설명
GET/api/meCognito JWT 사용자 동기화와 현재 사용자 조회
POST/api/projects프로젝트 생성
GET/api/projects내 프로젝트 목록 조회
GET/api/projects/{projectId}프로젝트 상세 조회
POST/api/projects/{projectId}/api-keysAPI Key 발급
GET/api/projects/{projectId}/api-keysAPI Key 목록 조회. raw key는 포함하지 않음
DELETE/api/projects/{projectId}/api-keys/{apiKeyId}API Key 폐기
GET/api/projects/{projectId}/assetsAsset 목록 조회
GET/api/projects/{projectId}/assets?key={key}Asset 상세/상태 조회
DELETE/api/projects/{projectId}/assets?key={key}Asset 삭제

12. Developer API 엔드포인트

MethodPath설명
POST/v1/assetsmultipart/form-data로 Asset 업로드
GET/v1/assetsAPI Key가 속한 프로젝트의 Asset 목록 조회
GET/v1/assets?key={key}논리 key로 Asset 상세/상태 조회
DELETE/v1/assets?key={key}논리 key로 Asset 삭제

13. 에러 처리

OneAsset API는 `success: false`와 `error.code`를 내려줍니다. 프론트는 code/status를 기준으로 inline error, page error, retry, login redirect로 변환합니다.

에러 코드 레퍼런스 보기