이슈 본연: API 레퍼런스의 미채움 마커 5종(실측 제외/TODO/필드 없음/대표 에러 없음)
1,194건을 코드에서 읽어 전수 채우고(0건), api:docgen 재생성이 사람이 채운 내용을
손실·열화시키던 멱등성 결함 4종(CRLF, 표 파이프 이스케이프, 에러 서술 보존, 중복
라우트명 키)을 근본 수정. --check 를 실측 제외와 드리프트가 구분되도록 재정의.
ParameterDescriber/ResourceFieldDescriber 에 leaf 폴백·SEO 스코프·공통 사전 확장.
파생 결함(문서 실측 중 발견): ResponseHelper 기본 메시지 키 6종이 존재하지 않는
messages.* 를 가리켜 응답 message 가 번역문 대신 키 문자열로 노출되던 문제를 common.*
으로 정정하고, 코어 7 + gdpr/marketing/pay_kginicis/verification/ecommerce 확장의
호출부와 누락 lang 키(게시판 10키 + 이커머스 category_images 4키 포함)를 ko/en/ja
전수 정정. 중복 그룹 키 2건은 기존 키로 호출부 통합.
보안: GET /api/identity/challenges/{id} 는 권한 가드 없는 공개 폴링 엔드포인트인데
Service::getStatus 가 attempts/max_attempts 를 응답에 담아 남은 시도 횟수를 추론할 수
있었다. 두 필드를 제거하고, 챌린지 화면(admin_basic/basic)의 서버 attempts 참조를
제거(남은 횟수 UI 는 query fallback + verify 실패 시 로컬 증가로 유지).
부수 정리(변경셋에 들어온 board 컨트롤러의 audit 사전 결함): FormRequest 4개 신설로
base Request 주입 제거, CommentController 의 Board 직접 호출을 BoardService 위임으로
전환, PHPDoc @return 보강. board 스위트에서 발견한 stale test 3건(seed SSoT 불일치,
admin 계정 user 역할 누락)도 같은 세션에서 정정.
버전 정렬(공개 release 기준): 코어 7.0.3→7.0.4, sirsoft-board 1.0.1→1.0.2,
verification_kginicis 1.0.0→1.0.1, admin_basic 1.0.1→1.0.4.
4.6 KiB
Images API 레퍼런스
소유: plugin
sirsoft-ckeditor5· 생성:php artisan api:docgen(실측 기반). @generated 블록은 재생성 시 갱신되며, 사람이 작성한 설명은 보존됩니다.
TL;DR (5초 요약)
1. 이 문서는 실제 API 호출로 실측한 Images 엔드포인트 레퍼런스입니다
2. 각 엔드포인트: 메서드/URI/권한 + 요청 파라미터 표 + 요청 예시(raw HTTP) + 실측 응답 필드 표 + 응답 예시(envelope)
3. 응답 필드의 예시값·응답 예시 JSON 은 실제 호출 응답에서 관측된 값입니다
4. 갱신: 코드 변경 후 php artisan api:docgen 재실행
5. 설명(TODO) 칸은 사람이 채웁니다
GET /api/plugins/sirsoft-ckeditor5/images/{hash}
- 라우트명:
api.plugins.sirsoft-ckeditor5.api.sirsoft-ckeditor5.images.serve - 컨트롤러:
Plugins\Sirsoft\Ckeditor5\Http\Controllers\ImageServeController@serve - 인증/권한: 공개 (인증 불필요)
요청 파라미터
| 이름 | 위치 | 타입 | 필수 | 허용값 | 용도 |
|---|---|---|---|---|---|
| hash | path | string | 예 | — | 업로드 시 발급된 12자리 소문자 16진수 이미지 해시(라우트 제약 [a-f0-9]{12}). 저장된 <img src> 의 마지막 경로 세그먼트로, 이 값으로 서빙할 이미지를 조회한다. |
요청 예시
GET /api/plugins/sirsoft-ckeditor5/images/{hash} HTTP/1.1
Host: api.example.com
Accept: application/json
응답 필드 (data 내부)
이 엔드포인트는 JSON data 를 반환하지 않습니다. 성공 시 ResponseHelper envelope 없이 이미지 바이너리를 그대로 스트리밍합니다 (Symfony\Component\HttpFoundation\StreamedResponse). 실패(404) 시에만 표준 JSON envelope 를 반환합니다.
성공 응답의 관측 가능한 표면은 본문(이미지 바이너리)과 다음 헤더입니다 (ImageServeService::serve() 가 StorageInterface::response() 에 전달).
| 헤더 | 타입 | 예시값 | 용도/설명 |
|---|---|---|---|
| Content-Type | string | image/jpeg |
업로드 레코드의 mime_type 값. 허용 MIME: image/jpeg, image/png, image/gif, image/webp |
| Cache-Control | string | public, max-age=31536000 |
공개 콘텐츠 이미지의 장기 캐싱 (1년) |
| Content-Disposition | string | inline; filename="photo.jpg" |
업로드 시 원본 파일명(original_name)을 파일명으로 사용 |
응답 예시
성공 시 (HTTP 200) — JSON 이 아닌 이미지 바이너리 본문:
HTTP/1.1 200 OK
Content-Type: image/jpeg
Cache-Control: public, max-age=31536000
Content-Disposition: inline; filename="photo.jpg"
<binary image data>
실패 시 (HTTP 404) — 표준 JSON envelope:
{
"success": false,
"message": "이미지를 찾을 수 없습니다.",
"data": null
}
에러 응답
| 상태코드 | 의미 | 발생 조건 |
|---|---|---|
| 404 | Not Found | hash 가 라우트 제약([a-f0-9]{12})에 맞지 않아 라우트 미매칭 / ImageServeService::findByHash() 가 업로드 레코드를 찾지 못함 / 레코드는 있으나 스토리지에 실제 파일이 없어 serve() 가 null 반환 (messages.image.not_found) |
설명
CKEditor5 본문에 삽입된 이미지를 실제로 내려주는 공개 서빙 엔드포인트다. 에디터가 저장한 HTML 의 <img src="/api/plugins/sirsoft-ckeditor5/images/{hash}"> 를 브라우저가 직접 GET 하므로 인증이 없다(PublicBaseController). 발행된 콘텐츠를 비로그인 독자가 열람하는 시나리오를 지원하기 위한 설계다.
{hash}는 라우트 제약where('hash', '[a-f0-9]{12}')로 12자리 소문자 16진수만 매칭된다. 형식이 어긋나면 라우트 자체가 매칭되지 않아 404 가 된다. 이 값은 이미지 업로드 시 발급된download_url의 마지막 경로 세그먼트다.- 성공 응답은 JSON 이 아니라 이미지 바이너리 스트림(
StreamedResponse,Content-Type은 이미지 MIME)이다.ResponseHelperenvelope 로 감싸지 않는다. ImageServeService::findByHash()가 레코드를 찾지 못하거나 스토리지에 실제 파일이 없어serve()가 null 을 반환하면messages.image.not_found(404) 표준 JSON 을 반환한다.
응답 예시 (실패 시에만 JSON — 성공 시에는 이미지 바이너리)
{ "success": false, "data": null, "message": "이미지를 찾을 수 없습니다.", "error": { "code": "not_found" } }