원문 캡처 · schematra.com
원문 캡처 · schematra.com

Schematra는 Chicken Scheme용 웹 프레임워크다. 제작자는 HTML을 데이터처럼 표현하는 Chiccup, 함수형 미들웨어, 쿠키 기반 세션을 제공하며 설정 없이 웹 앱을 시작할 수 있다고 소개한다.

설치는 chicken-install schematra를 실행하거나 Docker에서 docker run --rm -it ghcr.io/schematra/schematra:latest csi를 실행하는 방식이다. 이후 app.scm 같은 파일을 만들어 앱을 작성할 수 있다. 시작 안내와 문서를 참고할 수 있다.

사이트에는 Chiccup으로 UI를 구성하는 예제와 인증·로깅 미들웨어, JSON API, OAuth2 로그인, 웹훅 서명 검증 예제가 실려 있다. 서버 없이 격리된 앱 인스턴스에서 라우트를 시험하는 방법도 소개한다. 제작자는 앱을 단일 바이너리로 컴파일할 수 있고 런타임 의존성이 없다고 설명한다.

Schematra 0.7 소개 글은 WebSocket 지원과 프레임워크 도우미의 모듈별 재구성을 다룬다. 0.6.8 소개 글에는 JSON 액세스 로그와 0.6.x 수정 사항이 담겼다. Schematra 0.7 변경 사항 · Schematra 0.6.8 변경 사항

부록: 원문 예시

text
;; Webhook handler with HMAC-SHA256 signature verification ;; body-parser-middleware captures a replayable request body so you can verify it (import schematra schematra.body-parser hmac sha2 message-digest) (use-middleware! (body-parser-middleware)) (define (hmac-sha256-hex key data)   (message-digest->string    (hmac-message-digest (open-input-string key)                         sha256-primitive                         (open-input-string data) byte))) (define (signature-valid? secret raw sig)   (and sig        (string=? sig (string-append "sha256="                                     (hmac-sha256-hex secret raw))))) (post "/webhook"   (let* ((raw (request-body-string (current-request-body)))          (sig (alist-ref "x-hub-signature-256"                           (request-headers (current-request)) equal?)))     (if (signature-valid? (get-environment-variable "WEBHOOK_SECRET") raw sig)         (begin           (process-event! (read-json raw))           '(ok "Received"))         '(forbidden "Invalid signature")))) ;; Test without a live server — body: is captured by body-parser-middleware (define secret "test-secret") (define payload "{\"action\":\"push\"}") (define valid-sig (string-append "sha256=" (hmac-sha256-hex secret payload))) (test "rejects request with missing signature"   'forbidden   (test-route-status webhook-app 'POST "/webhook"                      body: payload)) (test "accepts request with valid signature"   'ok   (test-route-status webhook-app 'POST "/webhook"                      body: payload                      headers: