用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/kemalcr/kemal --skill kemal-middleware命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
Use when building, reviewing, debugging, testing, securing, or deploying web applications and HTTP APIs with the Kemal framework for Crystal. Covers Kemal routing, params, context, routers, filters, middleware, ECR, WebSockets, SSE, uploads, configuration, testing, and production concerns.
User authentication and session management in Kemal, following established project patterns.
Core Kemal development (routing verbs, parameters, modular router, version gates, response helpers).
正在显示 SKILL.md
| name | kemal-middleware |
| description | Creating and using custom middleware in Kemal using modern `use` keyword and handler classes. |
| license | MIT |
This skill provides expert guidance on creating and using custom middleware in Kemal, leveraging modern use registration and filter macros, strictly following patterns from kemal-by-example/webhook-inbox.
use registration (global and path-scoped): since Kemal 1.10.only / exclude with a single method and exact paths: all supported versions.only / exclude with "*" methods and "/*" path globs: Kemal master only — do not use the glob syntax on 1.12.0 or earlier, where it matches every path (see the warning below).Middleware Registration (use Keyword in Kemal 1.10+): Prefer use for clean global or path-scoped middleware registration:
# Path-scoped middleware (applies only to /api routes)
use "/api", [CORSHandler.new, AuthHandler.new]
# Global middleware (applies to all routes)
use CustomHandler.new
Configuration-based Registration: Alternatively, use Kemal.config.add_handler(CustomHandler.new). (The bare top-level add_handler is deprecated in favor of use and Kemal.config.add_handler).
Handlers: Create custom middleware by inheriting from Kemal::Handler:
class MyHandler < Kemal::Handler
def call(context)
# Execution prior to next handler
call_next(context)
# Execution after next handler returns
end
end
Selective Filtering in Handlers: Use only or exclude macros to restrict execution within the handler class. On Kemal 1.12.0 they support a single HTTP method and exact paths only:
class MyHandler < Kemal::Handler
only %w[/admin], "POST"
def call(context)
return call_next(context) unless only_match?(context)
# Custom logic
call_next(context)
end
end
On Kemal master, "*" matches all methods and paths ending in "/*" match a prefix:
# Kemal master only:
class MyHandler < Kemal::Handler
# Matches all HTTP methods on /admin and sub-paths
only %w[/admin/*], "*"
# ...
end
WARNING: Do not use "*" or "/*" globs on Kemal 1.12.0. The 1.12.0 route matcher treats * as a radix glob, so a rule like only %w[/admin/*], "*" matches every path on every method — an auth handler scoped this way locks the whole site. For middleware that should cover an entire path subtree on any version, prefer use "/admin", MyHandler.new instead.
Legacy Registration (add_handler): add_handler MyHandler.new remains supported for backward compatibility.
Specialized Handlers (HMAC): For HMAC signatures, require "kemal-hmac" and inherit from Kemal::Hmac::Handler:
class InboxHmacHandler < Kemal::Hmac::Handler
only %w[/hooks/inbox], "POST"
def call(context)
return call_next(context) unless only_match?(context)
super
end
end
require "kemal-hmac"
# Protects only `POST /hooks/inbox` with kemal-hmac.
class WebhookInbox::InboxHmacHandler < Kemal::Hmac::Handler
only %w[/hooks/inbox], "POST"
def call(context)
return call_next(context) unless only_match?(context)
super
end
end
require "kemal"
require "kemal-hmac"
require "db"
require "sqlite3"
require "./config/app"
require "./config/database"
require "./config/schema"
require "./helpers/headers_json"
require "./middleware/inbox_hmac_handler"
require "./models/webhook_event"
require "./routes/home"
require "./routes/inbox"
require "./routes/events"
# Configure HMAC handler with client/secret mapping and use keyword
client = WebhookInbox.webhook_client
use WebhookInbox::InboxHmacHandler.new({client => [WebhookInbox.webhook_secret]})
WebhookInbox::Schema.setup
Kemal.run
use "/path", Handler.new for path-scoped middleware instead of checking path conditions inside route blocks.Kemal::Hmac::Handler, pass key/secret maps as { "client_id" => ["secret_key"] }.