카테고리 목록
GET https://api.bootapi.com/v1/categories — 서버 Basic 인증을 사용해요.
const categories = await commerce.get('categories')javascript응답은 list 객체가 아닌 루트 카테고리 배열이에요.
[
{
"_id": "67c95e64d01640bb9859c629",
"name": "리빙",
"parent_category_id": "",
"status_display": true,
"status_best": false,
"filter_color": null,
"filter_size": null,
"children": []
}
]jsonchildren에 동일한 구조의 하위 카테고리가 들어가요. 목록은 프로젝트/판매자로 제한되어 있지만 status_display가 false인 카테고리도 포함할 수 있어 쇼핑몰 메뉴에서는 별도로 거르세요. 상품 목록 요청에는 선택한 카테고리 _id를 category_id로 보내요.
GET /v1/categories/:id는 단일 카테고리 객체를 반환해요. 단일 조회의 children은 하위 카테고리가 있어도 항상 빈 배열이에요. 전체 트리는 목록 API를 기준으로 구성해요.
카테고리 관리 API도 구현되어 있어요: POST /v1/categories, PUT /v1/categories/:id, DELETE /v1/categories/:id. 생성/수정 본문은 name, parent_category_id, status_display, status_best, filter_color, filter_size를 최상위에 보내요. 관리 작업에는 supervisor 역할 scope가 필요하며 공개 쇼핑몰 BFF에 노출하지 않아요.
옵션은 상품 상세에서 읽어요
GET /v1/products/:id의 options 배열을 사용해요. 목록의 options는 빈 배열이므로 목록에서 옵션이 비어 있다고 옵션 없는 상품으로 확정하지 않아요. option_count로 개수를 보고 상세에서 옵션을 읽어요.
| 필드 | 형태 | 설명 |
|---|---|---|
options[].product_option_id |
String | 구매 요청의 상품 옵션 ID |
options[].product_id |
String | 부모 상품 ID |
options[].keys |
String[] | 옵션 항목명 |
options[].name |
String[] | 항목별 값, 단일 문자열이 아님 |
options[].option |
Object | 예: { "색상": "블랙", "크기": "M" } |
options[].price |
Number | 옵션 금액. 선택 옵션은 상품 가격에 더해짐 |
options[].stock, use_stock |
Integer, Boolean | 옵션 재고와 관리 여부 |
options[].subscription_periods |
Array | 구독 기간별 옵션 설정 |
장바구니 요청의 product_option_id는 최상위 필드예요. 주문 준비 요청은 products[].option.product_option_id로 감싸야 해요. 주문 준비의 예제를 참고해요.
현재 v1에는 독립적인 products/:id/options 조회/관리 엔드포인트가 없어요. 상품 생성/수정 컨트롤러도 options 배열을 수집하지 않으므로 임의로 보내서 옵션이 생성된다고 가정하면 안 돼요.
확인 근거: V1::CategoriesController, Category::Search, Category::DataFormat, Product::DataFormat#options_data, ProductOption#option_data.
상품/옵션의 직렬화 ID는 운영 응답에서 product_id/product_option_id로 확인했어요. 로컬 모델의 _id 표기와 응답 serializer의 alias를 구분하고 실제 응답을 기준으로 연결해요.