kipchak 是做什麼的?
Kipchak 是 PHP 8.4 及以上版本的 API 開發套件。它基於 Slim Framework 4,具有固定的架構:啟動順序、外部服務的驅動程式、中介軟體,以及路由、控制器、資料傳輸物件(DTO)和 OpenAPI 的慣例。它執行於 FrankenPHP 的 worker 模式。文件:https://kipchak.dev;語言模型索引:https://kipchak.dev/llms.txt。
Kipchak 不是 Laravel 或 Symfony。 沒有 Facade、全域輔助函式、服務提供者、Eloquent、Blade、自動注入的控制器或隱藏慣例。端點所做的一切都在專案自身的程式碼中可見。請勿使用 request()、response()->json()、config('...')、app()、Route::get()、DB::、Cache:: 或任何其他框架輔助函式:這些在此處皆不存在。
識別 Kipchak 專案
composer.json 要求 kipchak/core,且專案具有以下資料夾。若專案有 AGENTS.md,請先閱讀:它描述了該專案。
| 路徑 | 內容 |
|---|---|
routes/ | 路由檔案。其中所有深度的 .php 檔案都會在啟動時載入。版本化的路由放在 routes/v1/。 |
api/Controllers/ | 控制器,命名空間 Api\Controllers;版本化的放在 v1/(Api\Controllers\v1)。 |
api/DataTransferObjects/ | DTO,版本方式與控制器相同。它們是 API 契約。 |
api/Models/ | 商業邏輯。 |
api/Entities/Doctrine/<Connection>/ | Doctrine 實體(使用 Doctrine 驅動程式時)。 |
api/Middlewares/ | 專案自有的 PSR-15 中介軟體。 |
api/OpenApi/Definition.php | OpenAPI 標題、版本、伺服器和共享回應。 |
api/Utils/ | 在 API 間共用的程式碼。 |
config/ | 每個驅動程式或中介軟體一個 PHP 檔案,回傳陣列,命名為 kipchak.<name>.php。 |
drivers/drivers.php | 依序初始化驅動程式。 |
middlewares/middlewares.php | 初始化應用於每個請求的中介軟體:首先且最後是 Error::initialise($app),其餘置於中間。 |
migrations/database/ | 適用於 Doctrine 驅動程式的純 SQL 遷移。 |
html/index.php | FrankenPHP worker 的入口點。極少編輯。 |
tests/ | 啟動 API 並向其發送請求的 PHPUnit 測試。 |
Kipchak\Core\Api::boot() 建構 Slim 應用程式,然後載入 drivers/drivers.php,接著是 middlewares/middlewares.php,最後是所有路由檔案,並回傳該應用程式。
在從 starter 建立的專案中(composer create-project kipchak/starter my-api)可使用的指令:
composer test:執行測試。每次變更後都應執行。composer openapi:將 OpenAPI 文件寫入openapi.yaml;若文件有問題則失敗。docker compose up --watch:在 http://localhost:8080 執行 API,檔案變更時自動重新啟動 worker。
規則
- 每個位於
api/和tests/的 PHP 檔案都以declare(strict_types=1);開頭。將類別設為final,除非它們被設計為可被繼承。為每個屬性、參數和回傳值指定型別。 - 控制器應輕薄。 讀取請求、呼叫模型、回傳回應。邏輯屬於
api/Models/。 - DTO 即契約。 每個請求和回應的形狀都是一個
final readonly的 DTO,帶有#[OA\Schema],且每個屬性都有#[OA\Property](包含描述和範例)。控制器使用ref: '#/components/schemas/Name'引用 DTO 的 schema,絕不內聯定義 DTO 的欄位。同一個 DTO 同時描述請求主體和回應。 - 回應透過
Kipchak\Core\Components\Http\Response::json($response, $data, $status)處理,該函式將$data包裝在封套{"code": 200, "status": "OK", "data": ...}中。 - 錯誤使用 Slim 的 HTTP 例外:
HttpNotFoundException、HttpBadRequestException、HttpUnauthorizedException、HttpForbiddenException、HttpMethodNotAllowedException。Error 中介軟體(kipchak/middleware-error)將它們轉換為相同的封套,例如{"code": 404, "status": "RESOURCE_NOT_FOUND", "data": "No order has the ID 9."}。任何其他例外都會變成 500 錯誤,其訊息不會暴露給客戶端。 - Worker 模式。 API 僅啟動一次,並從記憶體服務多個請求。切勿將請求資料保存在靜態屬性、全域變數或單例中。靜態變數僅能快取每個請求都相同的內容。
- 若存在 Kipchak 驅動程式,請優先使用它來存取服務,而非直接使用客戶端函式庫(請參閱 references/packages.md)。關聯式資料庫使用 Doctrine 驅動程式。
- 設定存在於
config/和環境變數中。使用Kipchak\Driver\Config\Config::get('kipchak.api')讀取設定檔,該函式回傳一個陣列。在設定檔內部使用Kipchak\Core\env('NAME', 'default')讀取環境變數。切勿在控制器或模型中呼叫getenv()。 - 日誌記錄在控制器中使用
$this->logger(Monolog,PSR-3);在其他地方使用Kipchak\Driver\Logger\Logger::get()。 - API 變更即契約變更。 同時更新 DTO 和控制器的屬性,然後更新測試,並檢查 OpenAPI 文件是否仍能無警告地產生。
新增端點
請遵循以下五個步驟。每個步驟的完整程式碼位於 references/endpoints.md;在撰寫端點之前請先閱讀。
- DTO 在
api/DataTransferObjects/v1/。 - 模型在
api/Models/:邏輯,回傳 DTO。使用 Valinor 將陣列映射到 DTO:(new MapperBuilder())->mapper()->map(Order::class, Source::array($row))。 - 控制器方法在
api/Controllers/v1/中,位於繼承Kipchak\Core\Components\Controllers\Base的類別上,簽名為(ServerRequestInterface $request, ResponseInterface $response, array $args): ResponseInterface,並帶有#[OA\Get]、#[OA\Post](等)屬性:路徑、operationId、摘要、標籤、參數、請求主體和回應。 - 路由在
routes/v1/<resource>.php中,位於/v1群組內:$group->get('/orders/{id:[0-9]+}', [Controllers\v1\Orders::class, 'get']); - 測試在
tests/中,繼承專案的ApiTestCase,測試成功和錯誤回應。若專案的 OpenAPI 測試列出了預期的路徑,請將新路徑加入。
參考資料
閱讀與任務相符的參考文件:
- references/endpoints.md:完整的資源(DTO、模型、控制器、路由、測試)、請求主體與驗證、查詢參數、路徑參數。
- references/drivers.md:使用驅動程式、設定、Doctrine,以及撰寫新的驅動程式。
- references/middleware.md:全域、群組和路由中介軟體、它們的順序,以及撰寫新的中介軟體。
- references/worker-mode.md:在長期運行的 worker 中安全的操作、請求主體、連線,以及在回應後的工作。
- references/packages.md:所有 Kipchak 驅動程式和中介軟體(免費版和企業版)。