학식
학교 식당 번호로 그 식당의 메뉴와 가격을 받고(cafeteria_menu), 식당 번호, 이름, 건물, 위치 목록을 받습니다(cafeteria_places). 로그인이 필요 없습니다. 학교에 식당 목록 API가 없어서 목록은 라이브러리가 번호 1부터 max_place_id까지의 메뉴 응답을 차례로 조회해 모은 것입니다. 공통 규칙은 공통 규칙입니다.
요청 파라미터
섹션 제목: “요청 파라미터”| 파라미터 | 타입 | 필수 | 기본값 | 설명 |
|---|---|---|---|---|
place_id (cafeteria_menu) |
문자열 | 필수 | 없음 | 학교의 식당 번호. 라이브러리에 번호표가 없으므로 cafeteria_places()로 확인 |
max_place_id (cafeteria_places) |
정수 | 선택 | 10 |
식당 목록을 만들 때 조회할 번호 범위 1~max_place_id. 식당이 늘어나면 올림 (최대 50, 벗어나면 요청 없이 INVALID_INPUT) |
- 이름 표기: Python은
snake_case, Node.js와 Java는camelCase입니다 (maxPlaceId). Node.js는cafeteriaMenu(placeId),cafeteriaPlaces({ maxPlaceId })이고, Java는cafeteriaMenu(String placeId),cafeteriaPlaces(),cafeteriaPlaces(int maxPlaceId)입니다. - 학교 요청:
GET https://www.sejong.ac.kr/kor/unilife/cafeteria-info.do?mode=getMenuList&placeId=<번호>, 응답 배열items. cafeteria_places는 같은 주소를 번호 1부터max_place_id까지 한 건씩 차례로 호출합니다 (병렬 요청 없음). 호출 한 번에 요청이 여러 번 나가는 유일한 메서드입니다.- 번호마다 응답의 첫 행에서 식당 한 곳을 만들고, 메뉴 행이 없는 번호는 목록에 더하지 않습니다. 같은
place_id는 한 번만 나오며 결과는 번호 순입니다.
응답 데이터 구조
섹션 제목: “응답 데이터 구조”식당 메뉴 cafeteria_menu 예시입니다 (필드 이름은 Python 기준, Node.js와 Java는 camelCase). 학교 데이터는 바뀌므로 값은 예시입니다.
[ { "place_id": "1", "place_name": "식당 이름", "building_name": "건물 이름", "location": "6층", "date": "2026-03-02", "day": "월", "meal_type_id": "1", "meal_name": "중식", "menu_name": "국 · 주반찬 · 김치", "price": "7000" }, { "place_id": "3", "place_name": "다른 식당", "building_name": "건물 이름", "location": "B1층", "date": "", "day": "", "meal_type_id": "", "meal_name": "", "menu_name": "라면", "price": "3300" }]식당 목록 cafeteria_places 예시입니다.
[ { "place_id": "1", "place_name": "식당 이름", "building_name": "건물 이름", "location": "6층", "extra": {} }]모든 필드는 문자열이고 없으면 빈 문자열입니다. 식당에 따라 날짜가 있는 주간 메뉴이거나 날짜 없는 상시 메뉴입니다. 상시 메뉴 식당의 행은 date, day, meal_type_id, meal_name이 빈 문자열입니다.
메뉴 (CafeteriaMenuItem, extra 없음)
섹션 제목: “메뉴 (CafeteriaMenuItem, extra 없음)”| 필드 | 학교 키 | 설명 |
|---|---|---|
place_id |
placeId |
식당 번호 |
place_name |
placeName |
식당 이름 |
building_name |
buildingName |
건물 |
location |
location |
위치 (예: 6층) |
date |
menuDate |
메뉴 날짜 (상시 메뉴 식당은 빈 문자열) |
day |
day |
요일 (상시 메뉴 식당은 빈 문자열) |
meal_type_id |
mealTypeId |
식사 구분 번호 (1 중식, 2 석식) |
meal_name |
mealName |
식사 이름 (학교 원문) |
menu_name |
menuName |
메뉴 이름 |
price |
price |
가격 (문자열, 예: 5500) |
라이브러리는 식사 구분 번호를 번역하지 않으니 학교가 주는 meal_name을 쓰세요.
식당 (CafeteriaPlace)
섹션 제목: “식당 (CafeteriaPlace)”| 필드 | 설명 |
|---|---|
place_id, place_name |
식당 번호, 이름 |
building_name, location |
건물, 위치 |
extra |
메뉴 필드(날짜, 요일, 식사, 메뉴 이름, 가격)를 뺀 나머지 학교 필드 |
실패 동작
섹션 제목: “실패 동작”- 번호마다 하루(기본 86400초) 캐시합니다. 학교 실패는 마지막 캐시 값, 없으면 빈 목록이고 캐시가 없는 실패는 60초(기본) 동안 요청 없이 빈 목록입니다.
cafeteria_places는 요청 하나라도 실패하면 목록 전체가 실패입니다. 일부만 하루 동안 캐시되는 일이 없도록 부분 목록은 캐시하지 않습니다.- 두 메서드 모두 학교 쪽 문제로 예외를 던지지 않습니다.
max_place_id가 범위를 벗어난 경우만INVALID_INPUT입니다. - 빈
cafeteria_menu는 번호가 틀린 것을 증명하지 않습니다. 없는 번호와 메뉴가 아직 올라오지 않은 날(휴일 포함) 모두 빈 목록입니다.
알려진 한계
섹션 제목: “알려진 한계”- 학교에 식당 목록 API가 없어
max_place_id를 넘는 번호의 식당은 찾지 못합니다. 식당이 늘어나면max_place_id를 올리세요. - 메뉴가 비어 있는 식당(주간 메뉴 미등록, 휴일)은 다음 갱신(기본 하루)까지 목록에서 빠집니다.
- 메뉴 번호가 없는 식당은 이 목록에 나올 수 없습니다.
- 식당 번호는 바뀔 수 있으니 번호를 코드에 적어 두기보다
cafeteria_places()로 확인하세요. 라이브러리는 번호로 이름을 짐작하지 않습니다. - 계약 원본: spec/PUBLIC_DATA.md
예시 코드
섹션 제목: “예시 코드”List<CafeteriaPlace> places = publicData.cafeteriaPlaces(); // 기본 10건 (maxPlaceId 인자로 최대 50), 하루 캐시List<CafeteriaMenuItem> menu = publicData.cafeteriaMenu("1"); // 1번 식당 메뉴places = public_data.cafeteria_places() # 기본 10건 (max_place_id 인자로 최대 50), 하루 캐시menu = public_data.cafeteria_menu("1") # 1번 식당 메뉴const places = await publicData.cafeteriaPlaces(); // 기본 10건 (maxPlaceId 인자로 최대 50), 하루 캐시const menu = await publicData.cafeteriaMenu('1'); // 1번 식당 메뉴