API 2를 사용할 때
외부 콜백·패키지 DB 기반을 쓰는 확장은 manifest api:2를 선언합니다. 기본 API 1의 route·서비스 연결을 유지하면서 별도의 외부 POST와 패키지 데이터 계약을 사용합니다. 실제 메서드와 manifest 스키마는 src/Extension 및 docs/extensions.md를 함께 확인합니다.
외부 콜백
Context::externalPost(path, authenticate, handler, maxBytes, contentType)로 세션과 독립적인 콜백을 등록합니다. 기본 JSON, PG 인증 폼은 application/x-www-form-urlencoded를 명시합니다. 인증 콜백과 본문 크기 제한을 반드시 둡니다.
서명·거래 키·상점·금액·환경을 확인하고 중복 요청을 같은 결과로 처리합니다. 임의 요청값으로 파일 경로·SQL 테이블명·외부 목적지를 만들지 않습니다. 외부 호출을 인증하지 않은 GET으로 상태 변경하지 않습니다.
DB와 등록 레지스트리
패키지 테이블은 API 2의 스키마 계약에 따라 등록하고 새 설치·기존 설치를 멱등하게 처리합니다. 코어 테이블을 직접 변경해 확장의 비활성화·삭제가 코어 기능을 망가뜨리지 않게 합니다. 접두어와 설치 레지스트리에 등록되는 백업 대상을 확인합니다.
확장 등록 시 실제 업무 데이터를 초기화하거나 과거 기록을 삭제하지 않습니다. 비활성화는 실행 여부를 바꾸며 기록의 삭제는 별도 승인된 작업입니다.
상태와 백업
영속 사용 상태는 storage/extensions의 잠금·원자적 교체 방식으로 관리합니다. enabled.json을 직접 덮어써 다른 확장의 상태를 지우지 않습니다. 런타임 캐시·외부 실행 허용값은 storage/extensions-runtime과 구분합니다.
수동 백업 v2는 등록된 확장 테이블과 영속 상태를 포함합니다. 패키지 PHP 소스·임시 잠금·런타임 토큰은 별도입니다. 복원 뒤에는 외부 실행 허용값을 폐기하고 계정·미완료 작업을 확인한 후 다시 허용합니다.
관리 POST에서 스키마 설치 예시
$schema = new \GnuCms\Extension\PackageSchema(
$context->app->db(), $context->app->storageDir()
);
$context->route('POST', '/install',
static function ($request, $response) use ($schema) {
$schema->install('modules/hello', 1, ['hello_records'],
static function ($db, int $previousVersion): void {
$db->execute('CREATE TABLE IF NOT EXISTS '
. $db->table('hello_records')
. ' (id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,'
. ' title VARCHAR(100) NOT NULL)'
. ' ENGINE=InnoDB DEFAULT CHARSET=utf8mb4');
});
return $response->withStatus(303)
->withHeader('Location', $request->getUri()->getPath());
}, admin: true);응답 Location은 예제 형태입니다. 실제 모듈에서는 설치 결과를 보여 줄 별도 GET 경로로 이동하세요. POST 폼에는 csrf_token을 넣습니다. 공개 GET·bootstrap·웹훅에서 install을 실행하지 않습니다.
테이블 목록은 접두어 없는 논리 이름이며 영문 소문자로 시작하는 소문자·숫자·밑줄 30자 이하입니다. 코어 테이블이나 다른 패키지 소유 테이블을 선언할 수 없습니다. 이전 소유 테이블은 레지스트리에서 유지하며 schema version을 낮추지 않습니다.
MySQL DDL은 일반 데이터 트랜잭션과 다르므로 install을 진행 중 트랜잭션 안에서 호출하지 않습니다. 실패 시 state=failed로 남고 멱등 DDL을 고친 뒤 명시적 관리 POST로 다시 실행합니다. ready 상태의 테이블이 사라져 있으면 전체 백업을 중단하므로 누락 원인을 먼저 해결합니다.
개발자 참고 소스
문서 파일 갱신 26-10-07 08:34:40