177 lines
3.9 KiB
Markdown
177 lines
3.9 KiB
Markdown
# 옆 프로젝트 API 연동 가이드
|
|
|
|
UNIARE v4부터 덱 데이터는 **공유 코드 + REST API**로 제공합니다.
|
|
URL 쿼리(`?cards=`) 방식은 사용하지 않습니다.
|
|
|
|
## 공식 엔드포인트
|
|
|
|
```http
|
|
GET https://uniare.sori.studio/api/v1/decks/:shareCode
|
|
```
|
|
|
|
### 응답 예시
|
|
|
|
```json
|
|
{
|
|
"v": 1,
|
|
"shareCode": "x7Kp9m2Q",
|
|
"shareType": "user",
|
|
"series": "ua36",
|
|
"seriesName": "마크로스",
|
|
"name": "블루 aggro",
|
|
"totalCards": 50,
|
|
"cards": [
|
|
{
|
|
"number": "UA36BT/MCR-1-052",
|
|
"count": 4,
|
|
"key": true,
|
|
"imgSrc": "/ua36/UA36BT_MCR-1-052.png",
|
|
"color": "Blue",
|
|
"rarity": "SR",
|
|
"trigger": null,
|
|
"parallel": false
|
|
}
|
|
],
|
|
"author": {
|
|
"id": 1,
|
|
"displayName": "닉네임",
|
|
"avatarUrl": null
|
|
},
|
|
"createdAt": "2026-06-19T12:00:00Z",
|
|
"updatedAt": "2026-06-19T12:00:00Z",
|
|
"viewCount": 42,
|
|
"isPublic": true
|
|
}
|
|
```
|
|
|
|
## shareCode 얻는 방법
|
|
|
|
| 방법 | 예시 |
|
|
|---|---|
|
|
| UNIARE 공유 버튼 | `https://uniare.sori.studio/d/x7Kp9m2Q` |
|
|
| URL 파라미터 | `cardList.html?d=x7Kp9m2Q` |
|
|
| 코드만 | `x7Kp9m2Q` |
|
|
|
|
## 클라이언트 라이브러리
|
|
|
|
프로젝트에 포함된 파일:
|
|
|
|
```
|
|
integrations/uadeck-deck-client.js
|
|
```
|
|
|
|
### 브라우저
|
|
|
|
```html
|
|
<script src="https://uniare.sori.studio/integrations/uadeck-deck-client.js"></script>
|
|
<script>
|
|
const client = new UaDeckDeckClient({
|
|
baseUrl: 'https://uniare.sori.studio/api/v1',
|
|
imageBase: 'https://uniare.sori.studio',
|
|
});
|
|
|
|
// 공유 링크에서 덱 로드
|
|
const deck = await client.fetchFromUrl('https://uniare.sori.studio/d/x7Kp9m2Q');
|
|
|
|
deck.cards.forEach((card) => {
|
|
console.log(card.number, card.count, card.imageUrl);
|
|
});
|
|
</script>
|
|
```
|
|
|
|
### Node.js / ESM
|
|
|
|
```javascript
|
|
import { UaDeckDeckClient } from './integrations/uadeck-deck-client.js';
|
|
|
|
const client = new UaDeckDeckClient({
|
|
baseUrl: 'https://uniare.sori.studio/api/v1',
|
|
});
|
|
|
|
const deck = await client.fetchDeck('x7Kp9m2Q');
|
|
```
|
|
|
|
### fetch 직접 사용
|
|
|
|
```javascript
|
|
const res = await fetch('https://uniare.sori.studio/api/v1/decks/x7Kp9m2Q');
|
|
const deck = await res.json();
|
|
|
|
if (!res.ok) throw new Error(deck.error);
|
|
```
|
|
|
|
## 이미지 URL 규칙
|
|
|
|
API의 `imgSrc`는 상대 경로입니다. 전체 URL:
|
|
|
|
```
|
|
https://uniare.sori.studio/images{imgSrc}
|
|
```
|
|
|
|
예: `imgSrc: "/ua36/UA36BT_MCR-1-052.png"`
|
|
→ `https://uniare.sori.studio/images/ua36/UA36BT_MCR-1-052.png`
|
|
|
|
`UaDeckDeckClient`는 `card.imageUrl`에 자동 변환합니다.
|
|
|
|
## CORS
|
|
|
|
다른 도메인에서 브라우저 `fetch`를 쓰려면 UNIARE 서버 `.env`의 `CORS_ORIGINS`에 해당 origin을 추가하세요.
|
|
|
|
```
|
|
CORS_ORIGINS=https://your-app.sori.studio,https://uniare.sori.studio
|
|
```
|
|
|
|
서버 간 호출(Node, Python 등)은 CORS가 필요 없습니다.
|
|
|
|
## 마이그레이션 (기존 ?cards= 코드)
|
|
|
|
**Before (폐기):**
|
|
|
|
```javascript
|
|
const params = new URLSearchParams(location.search);
|
|
const cards = JSON.parse(decodeURIComponent(params.get('cards')));
|
|
```
|
|
|
|
**After:**
|
|
|
|
```javascript
|
|
const code = UaDeckDeckClient.parseShareCode(location.href)
|
|
|| new URLSearchParams(location.search).get('d');
|
|
|
|
const client = new UaDeckDeckClient({ baseUrl: '/api/v1' });
|
|
const deck = await client.fetchDeck(code);
|
|
const cards = deck.cards;
|
|
```
|
|
|
|
## 공개 덱 목록
|
|
|
|
```http
|
|
GET /api/v1/decks/presets
|
|
```
|
|
|
|
```json
|
|
{
|
|
"presets": [
|
|
{
|
|
"share_code": "a7f3b2c1",
|
|
"series": "ua36",
|
|
"series_name": "마크로스",
|
|
"name": "공식 블루 템플릿",
|
|
"view_count": 120
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
엔드포인트 이름은 레거시 호환을 위해 `presets`를 유지하지만, 현재 응답 대상은 관리자가 등록한 프리셋이 아니라 사용자가 공개한 미만료 덱입니다.
|
|
|
|
상세 조회는 동일하게 `GET /decks/:shareCode`를 사용합니다.
|
|
|
|
## 에러 코드
|
|
|
|
| HTTP | 의미 |
|
|
|---|---|
|
|
| 404 | shareCode 없음 |
|
|
| 403 | 비공개 덱 |
|
|
| 410 | 만료된 임시 공유 (비회원 30일) |
|