php-api について
PHP API Development Skillは、PHP APIの設計と実装を学ぶ開発者向けのスキルです。REST、GraphQL、認証、ドキュメント、バージョニング、セキュリティを扱い、学習モジュールはレベル別に構成されています。
主な機能
- 01RESTおよびGraphQL API設計
- 02認証方式
- 03OpenAPIとSwaggerのドキュメント
- 04APIのバージョニングとセキュリティ
- 05レベル別の学習モジュール
活用シーン
- 01LaravelでのREST API設計
- 02JWT認証の実装
- 03APIセキュリティとレート制限の確認
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ pluginagentmarketplace/ custom-plugin-php --skill php-apiインストール後、Claude Code で/php-apiを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
assets/config.yamlschema.jsonreferences/GUIDE.mdPATTERNS.mdscripts/validate.py詳細
PHP API 開発スキル
PHP での API 設計と実装を習得するためのアトミックスキル
概要
REST 設計、GraphQL、認証戦略、API ドキュメントを網羅した、PHP API 開発のための包括的なスキルです。
スキルのパラメーター
入力の検証
interface SkillParams {
topic:
| "rest" // RESTful API design
| "graphql" // GraphQL with PHP
| "authentication" // JWT, OAuth 2.0
| "documentation" // OpenAPI, Swagger
| "versioning" // API versioning strategies
| "security"; // Rate limiting, CORS
level: "beginner" | "intermediate" | "advanced";
framework?: "laravel" | "symfony" | "slim";
auth_method?: "jwt" | "oauth2" | "api_key";
}
検証ルール
validation:
topic:
required: true
allowed: [rest, graphql, authentication, documentation, versioning, security]
level:
required: true
framework:
default: "laravel"
学習モジュール
モジュール 1:REST API の設計
beginner:
- Resource naming conventions
- HTTP methods semantics
- Status codes usage
intermediate:
- Pagination patterns
- Filtering and sorting
- HATEOAS basics
advanced:
- Hypermedia APIs
- Conditional requests
- Bulk operations
モジュール 2:認証
beginner:
- API keys
- Basic auth
- Token basics
intermediate:
- JWT implementation
- Refresh tokens
- Token revocation
advanced:
- OAuth 2.0 flows
- PKCE
- Scopes and permissions
モジュール 3:API セキュリティ
beginner:
- Input validation
- Output encoding
- CORS basics
intermediate:
- Rate limiting
- Request throttling
- API versioning
advanced:
- Security headers
- Request signing
- Audit logging
エラーハンドリングと再試行ロジック
errors:
VALIDATION_ERROR:
code: "API_001"
http_status: 422
recovery: "Return field-level errors"
AUTH_ERROR:
code: "API_002"
http_status: 401
recovery: "Check token, suggest refresh"
RATE_LIMIT_ERROR:
code: "API_003"
http_status: 429
recovery: "Return Retry-After header"
retry:
max_attempts: 3
backoff:
type: exponential
initial_delay_ms: 100
コード例
REST コントローラー(Laravel)
<?php
declare(strict_types=1);
namespace App\Http\Controllers\Api\V1;
use App\Http\Controllers\Controller;
use App\Http\Requests\StoreUserRequest;
use App\Http\Resources\UserResource;
use App\Models\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Response;
final class UserController extends Controller
{
public function index()
{
$users = User::query()
->with(['profile'])
->filter(request(['search', 'status']))
->paginate(request('per_page', 15));
return UserResource::collection($users);
}
public function store(StoreUserRequest $request): JsonResponse
{
$user = User::create($request->validated());
return (new UserResource($user))
->response()
->setStatusCode(Response::HTTP_CREATED)
->header('Location', route('api.v1.users.show', $user));
}
public function show(User $user): UserResource
{
return new UserResource($user->load('profile'));
}
public function destroy(User $user): Response
{
$this->authorize('delete', $user);
$user->delete();
return response()->noContent();
}
}
エラーレスポンス(RFC 7807)
<?php
declare(strict_types=1);
namespace App\Http\Responses;
final class ProblemDetails
{
public static function validation(array $errors): array
{
return [
'type' => 'https://api.example.com/errors/validation',
'title' => 'Validation Error',
'status' => 422,
'detail' => 'The request contains invalid data',
'errors' => $errors,
];
}
public static function unauthorized(): array
{
return [
'type' => 'https://api.example.com/errors/unauthorized',
'title' => 'Unauthorized',
'status' => 401,
'detail' => 'Authentication required',
];
}
}
JWT 認証
<?php
declare(strict_types=1);
namespace App\Services;
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
final class JwtService
{
public function __construct(
private readonly string $secret,
private readonly string $algorithm = 'HS256',
private readonly int $ttl = 3600,
) {}
public function generate(array $payload): string
{
$issuedAt = time();
return JWT::encode([
...$payload,
'iat' => $issuedAt,
'exp' => $issuedAt + $this->ttl,
], $this->secret, $this->algorithm);
}
public function decode(string $token): object
{
return JWT::decode($token, new Key($this->secret, $this->algorithm));
}
}
OpenAPI 仕様
openapi: 3.1.0
info:
title: User API
version: 1.0.0
paths:
/api/v1/users:
get:
summary: List users
parameters:
- name: page
in: query
schema:
type: integer
responses:
'200':
description: Success
content:
application/json:
schema:
$ref: '#/components/schemas/UserCollection'
post:
summary: Create user
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateUser'
responses:
'201':
description: Created
components:
schemas:
User:
type: object
properties:
id:
type: integer
email:
type: string
format: email
name:
type: string
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
security:
- bearerAuth: []
レート制限(Laravel)
<?php
// RouteServiceProvider or bootstrap/app.php
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Support\Facades\RateLimiter;
RateLimiter::for('api', function ($request) {
return Limit::perMinute(60)
->by($request->user()?->id ?: $request->ip())
->response(function () {
return response()->json([
'type' => 'https://api.example.com/errors/rate-limit',
'title' => 'Too Many Requests',
'status' => 429,
], 429)->header('Retry-After', 60);
});
});
トラブルシューティング
| 問題 | 原因 | 解決策 |
|---|---|---|
| CORS エラー | ヘッダーが不足しています | CORS ミドルウェアを設定します |
| JWT が無効です | 期限切れ、またはシークレットが正しくありません | exp クレームを確認し、シークレットを検証します |
| 429 エラー | レート制限に達しています | バックオフを実装し、レスポンスをキャッシュします |
| リソースで N+1 が発生します | イーガーローディングがありません | コントローラーで with() を使用します |
品質指標
| 指標 | 目標 |
|---|---|
| レスポンス時間 | <200ms P95 |
| エラー率 | <0.1% |
| ドキュメント | 100% のエンドポイント |
| テストカバレッジ | ≥90% |
使用方法
Skill("php-api", {topic: "authentication", level: "intermediate"})
コメント
Markdown 対応