engineering-best-practices-2026 について
多くの言語、フレームワーク、データシステムを扱う AI コーディングエージェント向けのエンジニアリング指針です。共通原則と技術スタック別の推奨事項をまとめ、コード生成、レビュー、リファクタリングに役立ちます。
主な機能
- 01複数スタック共通の原則
- 02セキュリティと性能の指針
- 03アーキテクチャと API の推奨事項
- 04言語・フレームワーク別の章
- 05CI/CD と可観測性の実践
活用シーン
- 01セキュリティ観点でのコードレビュー
- 02対象スタックのアプリのリファクタリング
- 03サービスや API のコード生成
- 04アクセシビリティとエラー処理の確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ skylarng89/ engineering-best-practices-skill --skill engineering-best-practices-2026インストール後、Claude Code で/engineering-best-practices-2026を入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
.gitignoreCONTRIBUTING.mdLICENSECHANGELOG.mdREADME.md.github/workflows/release.ymlauto-tag.ymlvalidate.yml.well-known/skills/index.jsondiscovery spec/evals/evals.json詳細
エンジニアリングのベストプラクティス — 2026 年版
LLM と AI コーディングエージェント向けの包括的な SKILL.md です。
リストに記載されているすべてのスタックで、コードの生成、レビュー、リファクタリングを行う際に、これらのルールを適用してください。
目次
- 基本原則
- Node.js
- Next.js
- NestJS
- Java
- Spring Boot
- Python
- Elixir
- Phoenix
- Erlang
- Rust
- Go (Golang)
- React
- Vue
- Nuxt
- Astro
- SQL / NoSQL
基本原則
以下は、あらゆる言語とフレームワークに適用されます。決して違反しないでください。
セキュリティ
- デフォルトでゼロトラストを徹底してください。 エッジ/ミドルウェアだけでなく、すべてのレイヤーで認証と認可を行います。
- 境界ですべての入力を検証・サニタイズします(スキーマ検証:Zod、Joi、class-validator、Pydantic など)。
- 機密データ(パスワード、トークン、PII、カード番号)を決してログに記録しないでください。
- すべての通信に TLS 1.3 を使用します。HTTPS を強制し、平文通信を拒否します。
- シークレットは環境変数またはシークレットマネージャー(Vault、AWS Secrets Manager)に保存します。決してコミットしないでください。
- OWASP Top 10 の緩和策をデフォルトで適用します(インジェクション、認証の不備、XSS、CSRF、SSRF など)。
- 依存関係のバージョンを固定します。プッシュのたびに CI で
audit/trivy/snykを実行します。 - サービスアカウント、DB ロール、IAM ポリシーには最小権限の原則を適用します。
パフォーマンス
- 最適化の前にプロファイリングを行います。APM(OpenTelemetry、Jaeger、Zipkin)と構造化メトリクスを使用します。
- I/O 待ちが中心の処理には非同期/ノンブロッキング I/O を優先し、CPU 負荷の高いタスクにはワーカースレッド/プロセスを使用します。
- 適切なレイヤー(CDN → アプリケーションキャッシュ → DB クエリーキャッシュ)で積極的にキャッシュします。明示的に無効化します。
- すべてのデータベースでコネクションプーリングを使用します。ワークロードに応じてプールサイズを調整します。
- N+1 クエリーを避けます。イーガーローディング/DataLoader/一括フェッチを使用します。
- すべてのリストエンドポイントでページネーションを行います。件数が無制限の結果セットを返さないでください。
冪等性
- 再試行される可能性がある、状態を変更するすべての HTTP エンドポイント(POST、PUT、PATCH、DELETE)は、必ず冪等にします。
- クライアント指定またはサーバー生成の冪等性キーを使用し、TTL 付きの重複排除テーブルに保存します。
- バックグラウンドジョブとメッセージコンシューマーは、冪等になるように設計します(少なくとも 1 回の配信が標準です)。
原子性とトランザクション
- 複数ステップの変更はデータベーストランザクションで囲みます。すべて成功した場合にのみコミットし、エラーが発生した場合はロールバックします。
- 分散システムでは、分散 2PC の代わりに Saga パターン(コレオグラフィーまたはオーケストレーション)を使用します。
- 競合が多い行には 楽観的ロック(
version/updated_at列)を適用します。 - 最後の防御策として データベースレベルの制約(UNIQUE、FK、CHECK)を使用します。
並行性
- 共有された可変状態を避けます。メッセージパッシング、不変データ構造、アクターを優先します。
- 言語固有の並行処理プリミティブ(goroutine、BEAM プロセス、仮想スレッド、async/await)を使用します。
- 適切な同期機構(ミューテックス、チャネル、STM、CRDT)で共有状態を保護します。
- バックプレッシャーを考慮して設計します。有界キュー、サーキットブレーカー、レート制限を使用します。
可観測性
- 相関 ID、トレース ID、重大度、タイムスタンプを含む構造化ログ(JSON)を出力します。
- OpenTelemetry で計装し、トレース、メトリクス、ログを 1 つの SDK で統合します。
- SLO/SLA を定義し、しきい値だけでなくエラーバジェットの消費率に基づいてアラートを設定します。
- すべてのサービスに
/health(生存確認)と/ready(準備状態)のヘルスチェックエンドポイントを設けます。
アクセシビリティ(UI)
- 最低基準として WCAG 2.2 AA に準拠します。一般公開製品では AAA を目指します。
- セマンティック HTML 要素を使用します。
<div>や<span>を乱用しないでください。 - すべてのインタラクティブ要素をキーボードで操作できるようにし、フォーカス状態を視覚的に示します。
- セマンティック HTML では不十分な場合に限り、ARIA のロール/ラベルを指定します。
- スクリーンリーダー(NVDA、VoiceOver)と自動化ツール(axe-core、Lighthouse)でテストします。
- 通常のテキストでは 4.5:1 以上、大きなテキストでは 3:1 以上の色のコントラスト比を確保します。
エラー処理
- 開発環境では速やかに明確なエラーを発生させ、本番環境では適切に処理します。
- エラーを黙って無視しないでください(
catch(e) {})。 - 構造化されたエラーレスポンスを返します:
{ code, message, details?, traceId }。 - 運用上のエラー(クライアントエラー、ネットワーク)とプログラマーエラー(バグ)を区別します。
- 言語ごとに型付きエラー階層を使用し、文字列だけで型を表すエラーは避けます。
API 設計
- REST:リソース指向の設計に従い、HTTP 動詞を意味に沿って使用し、適切なステータスコードを返します。
- 初日から API をバージョン管理します(
/v1/)。既存のクライアントを破壊しないでください。 - OpenAPI 3.1 / AsyncAPI でドキュメントを作成します。ドキュメントはコードと同じ場所に置き(手動ではなく生成します)。
- GraphQL:クエリの深さと複雑さに上限を設けます。バッチ処理には DataLoader を使用します。
- すべての公開エンドポイントにレート制限を適用します。
Retry-Afterを付けて429を返します。
CI/CD
- 速やかに失敗させます:lint → type-check → unit test → integration test → security scan → build → deploy。
- ブランチ保護を適用し、マージ前に CI の成功を必須にします。
- セマンティックバージョニング(
semver)を使用します。リリースにタグを付け、変更履歴を自動生成します。 - 不変のアーティファクト(Git SHA でタグ付けされたコンテナイメージなど)を優先します。本番環境では
latestを使用しないでください。
Node.js
ベースライン:Node.js 22 LTS(Active)または Node.js 24(Current)。EOL バージョンは避けてください。
プロジェクト構成
src/
config/ # env validation (zod/envalid)
routes/ # thin HTTP handlers
services/ # business logic
repositories/ # data access
middleware/
utils/
types/
ランタイムとパフォーマンス
- 該当する場合は
--enable-source-mapsと--experimental-vm-modulesを使用します。 - コンテナの RAM に適した
--max-old-space-sizeを有効にします。 - CPU 負荷の高いタスクには
worker_threadsを使用し、イベントループを決してブロックしないでください。 - リクエスト単位のコンテキスト(相関 ID)には
AsyncLocalStorageを使用します。スレッドローカルやグローバルは使用しないでください。 - 最適化の前に
clinic.js(flame、bubbleprof、heap profiler)でプロファイリングします。 - ロギングには
pino(最速の JSON ロガー)を使用し、本番環境ではconsole.logを避けます。
セキュリティ
- すべての Express/Fastify アプリで
helmetを使用します。CSP は明示的に設定し、デフォルト設定は使用しないでください。 corsには明示的な許可リストを適用し、本番環境ではorigin: '*'を決して使用しないでください。express-rate-limitまたは@fastify/rate-limitでレート制限を行います。複数インスタンスのデプロイでは Redis ストアを使用します。- すべてのリクエストボディ、パラメーター、クエリを、ビジネスロジックに渡す前に Zod または Joi で検証します。
- パスワードのハッシュ化には
argon2またはbcryptを使用します(md5、sha1、sha256単独は決して使用しないでください)。 - HTML 出力は
DOMPurify(ブラウザー)またはsanitize-html(サーバー)でサニタイズします。 NODE_ENV=productionを設定し、詳細なエラー情報の漏えいを防ぎます。- 依存関係を監査します:CI で
npm audit --audit-level=highを実行し、Dependabot または Renovate で自動化します。 eval()、new Function()、ユーザー入力を使ったchild_process.exec()は避けます。引数配列を使ってexecFile()を使用します。
非同期処理と並行処理
- コールバックや生の Promise による
.then()チェーンよりもasync/awaitを優先します。 - Promise は必ず
awaitします。エラー処理が明示されていない限り、結果を待たずに実行しないでください。 - 一部の失敗を許容できる場合は
Promise.allSettled()を、許容できない場合はPromise.all()を使用します。 unhandledRejectionとuncaughtExceptionイベントを処理し、ログを記録して適切に終了します。- 大きなデータにはストリーミング(
stream.pipeline)を使用し、ファイル全体をメモリにバッファリングしないでください。
モジュールシステム
- 新しいプロジェクトでは ESM(
"type": "module")を使用します。CJS と ESM の混在は避けてください。 - 必要なものだけをインポートし、
import * fromは避けてください。 tsconfig.jsonのpathsとバンドラーのリゾルバーを使って、パスエイリアス(@/→src/)を使用します。
TypeScript(強く推奨)
tsconfig.jsonで"strict": trueを使用します。正当な理由なしにanyを使用しないでください。- すべての公開関数に明示的な戻り値の型を定義します。
- 外部データには
anyではなくunknownを使用し、型ガードで型を絞り込みます。 - オブジェクトの形状を検証しつつ型の拡大を防ぐには、
satisfies演算子を使用します。
依存関係の管理
- CI では正確なバージョンに固定します(
npm ci)。 .npmrcでsave-exact=trueを設定します。- モノレポでは
pnpmを優先します(厳密な分離、ディスク効率)。 - 未使用の依存関係を定期的に削除します。
depcheckを使用します。
Next.js
ベースライン:Next.js 15.2.3+(CVE-2025-29927 に対応するパッチを含みます)。新規プロジェクトではすべて App Router を使用してください。
アーキテクチャ
- デフォルトでは React Server Components(RSC) を優先してください。ブラウザー API、イベントハンドラー、React の状態が必要な場合にのみ
'use client'を追加してください。 - Server Components は軽量に保ってください。キャッシュされない限り、リクエストごとに実行されます。複雑なロジックはサービスに配置してください。
- フォームの変更処理には Server Actions を使用してください。DB 操作の前に、サーバー側で Zod による検証を行ってください。
- ルートセグメントを同じ場所にまとめてください:
app/(auth)/login/page.tsx、app/api/v1/users/route.ts。
セキュリティ
- 認証を Middleware のみに依存させないでください(CVE-2025-29927 の教訓)。すべての Route Handler、Server Action、Data Access Layer(DAL)で本人確認を再検証してください。
- DAL を実装してください。すべての DB アクセスを担い、認証チェックを行う単一のモジュールです。
- セッションには
HttpOnly; Secure; SameSite=StrictCookie を使用してください。トークンをlocalStorageに保存しないでください。 - セッションの
maxAgeを設定してください。一般ユーザーは 24 時間、管理者ルートは 15 分にします。権限昇格時にはセッション ID をローテーションしてください。 next.configのヘッダーでContent-Security-Policy、X-Frame-Options、X-Content-Type-Optionsを設定してください。dangerouslySetInnerHTMLは使用しないでください。どうしても必要な場合は、最初にDOMPurifyでサニタイズしてください。images.remotePatternsとfetchラッパーで SSRF 許可リストを設定してください。- CSRF:組み込みの Server Action CSRF 対策を使用してください。レガシーなフォームルートには明示的なトークンを追加してください。
パフォーマンス
- すべての画像に
next/imageを使用してください。遅延読み込み、WebP 変換、サイズ最適化に対応しています。 - フォントには
next/fontを使用してください。セルフホストされ、レイアウトシフトが発生しません。 - Partial Pre-rendering(PPR)(Next.js 15)を活用してください。Suspense を使って、静的なシェルと動的な領域を組み合わせます。
- 高コストな Server Components には、本当に必要な場合にのみ
export const dynamic = 'force-dynamic'を指定してください。 unstable_cache/revalidateTagを使用して、きめ細かなキャッシュ無効化を行ってください。- CI パイプラインで Lighthouse CI と Core Web Vitals を使って測定してください。
- クライアントバンドルは最小限にしてください。容量の大きなクライアントコンポーネントには
import dynamic from 'next/dynamic'を使用してください。
データ取得
- 可能な場合は Server Components でデータを取得してください。API への往復が不要で、DB/サービスに直接アクセスできます。
- React の
cache()を使用して、単一のレンダーパス内でリクエストを重複排除してください。 - クライアント側のデータには、適切な stale-while-revalidate 戦略とともに React Query/SWR を使用してください。
エラー処理
- 分離されたエラー復旧を実現するため、各ルートセグメントの境界に
error.tsxを実装してください。 - 404 処理には
not-found.tsxを実装してください。 - スタックトレースや内部パスをクライアントに公開しないでください。
NestJS
ベースライン:NestJS 11+、Node.js 22 LTS。
アーキテクチャ
- モジュラーアーキテクチャに従ってください。ドメインごとにモジュールを作成します(
UserModule、AuthModule、PaymentModule)。 - Controller は薄く保ってください。入力を検証し、Service に処理を委譲して、HTTP レスポンスを返します。
- ビジネスロジックは Service に、データアクセスは Repository/DAO に配置してください。
class-validator、class-transformer、グローバルValidationPipe({ whitelist: true, forbidNonWhitelisted: true })とともに DTO を使用してください。- 認証/認可には Guard、横断的な処理(ログ記録、変換)には Interceptor、エラーのマッピングには Filter を使用してください。
セキュリティ
ThrottlerGuardをグローバルに適用してください。機密性の高いエンドポイント(認証、パスワードリセット)では、ルートごとに設定を上書きしてください。@nestjs/passportとpassport-jwtを使用してください。JwtAuthGuardで保護されたすべてのルートにおいて JWT を検証してください。- 機密性の高い設定をコードに保存しないでください。
@nestjs/configを使用し、Joi スキーマで環境変数を検証してください。 main.tsでapp.use(helmet())を呼び出して Helmet を適用してください。- CORS を明示的に有効化してください:
app.enableCors({ origin: allowlist, credentials: true })。 - 単純なロールチェックを超えるきめ細かな権限チェックには、
caslまたはカスタム RBAC Guard を使用してください。
パフォーマンス
- 高スループットのシナリオでは、Express より Fastify アダプター(
@nestjs/platform-fastify)を使用します。 ClassSerializerInterceptorとExclude()を組み合わせてレスポンスをシリアライズし、データ漏洩を防ぎます。- 読み取りが多く処理コストの高いエンドポイントでは、Redis と
CacheInterceptorを使用します。 - 非同期のバックグラウンド処理には、NestJS キュー(
@nestjs/bullまたは@nestjs/bullmq)を使用します。 - すべてのサービス/リポジトリのメソッドで
asyncを使用します。同期的なファイル I/O は使用しないでください。
テスト
- Jest のモックを使用して、サービスとガードを個別に単体テストします。
@nestjs/testingのTest.createTestingModule()を使用してモジュールを結合テストします。- アプリケーション全体を対象に、
supertestで E2E テストを実施します。
Java
基準:Java 21 LTS 以上。新規プロジェクトには Java 25 LTS を推奨します(2025年9月リリース)。
最新の言語機能
- 冗長な POJO の代わりに、不変のデータキャリアには レコード を使用します。
- 網羅的な型階層には、シールドクラス と パターンマッチング(
switch式)を使用します。 - 複数行の文字列(SQL、JSON、HTML)には テキストブロック を使用します。SQL 文字列を連結しないでください。
- 文脈から型が明らかな場合は、ローカル変数の型推論に
varを使用します。 Optional<T>は適切に使用します。nullable な値の戻り値の型としてのみ使用し、フィールドやパラメーターには使用しないでください。- 不変コレクションを優先します:
List.of()、Map.of()、Set.of()。
並行処理 — 仮想スレッド(Java 21 以降)
- I/O バウンドの処理には 仮想スレッド(
Thread.ofVirtual())を使用します。軽量なため、同時に数百万個を作成できます。 - 仮想スレッドをプールしないでください。タスクごとに新しいスレッドを作成します。
Executors.newVirtualThreadPerTaskExecutor()。 - Java 24 以降:仮想スレッドは
synchronizedでピン留めされなくなりました(JEP 491)。それでも、長時間にわたるsynchronizedブロックは避けてください。 - フォークしたサブタスクのライフサイクル管理には、構造化並行性(Java 25 でプレビューの
StructuredTaskScope)を使用します。 - 仮想スレッドでコンテキストを伝播する際は、
ThreadLocalの代わりに スコープ付き値(Java 21 以降)を使用します。 - プラットフォームスレッドとリアクティブプログラミングは、真に CPU バウンドのワークロード向けに確保します。
セキュリティ
PreparedStatementまたは JPA の名前付きパラメーターを使用し、SQL 文字列を連結しないでください。- パスワードは
bcryptまたはargon2(spring-security-crypto)でハッシュ化します。SHA-* のみは使用しないでください。 - Bean Validation(
@Valid、@NotNull、@Size)を使用して、外部入力をすべて境界で検証します。 SecurityManager相当の制御を適用し、信頼できないコードでのリフレクションやファイルアクセスを制限します。- 依存関係を最新の状態に保ちます。CI では
dependency-check-mavenまたは Snyk を使用します。 - 信頼できないデータを Java のネイティブデシリアライズでデシリアライズしないでください。JSON または Protobuf を優先します。
パフォーマンス
- GC を調整します。レイテンシが重要なサービスでは ZGC または G1GC、一貫した一時停止時間の目標には Shenandoah を優先します。
- クラスデータ共有(CDS) と AOT コンパイル(Project Leyden)を使用して、起動を高速化します。
- 接続プールには、
maximumPoolSizeを調整した HikariCP(Spring Boot のデフォルト)を使用します。 - 不要なボクシング/アンボクシングを避けます。一括数値処理にはプリミティブストリーム(
IntStream、LongStream)を使用します。 - 最適化の前に async-profiler でプロファイリングします。
コード品質
@Nullable/@NonNullアノテーション(Spring Boot 4 以降では JSpecify)を一貫して適用します。- CI では SpotBugs、Checkstyle、PMD によるチェックを必須にします。
- JUnit 5 と AssertJ で単体テストを作成します。結合テストには Testcontainers を使用します。
- 循環的複雑度を低く保ちます。メソッドを切り出し、継承よりコンポジションを優先します。
Spring Boot
基準:Spring Boot 4.0(Spring Framework 7、Java 17 以上、Java 25 に最適化)。SB4 にまだ移行していないプロジェクトには Spring Boot 3.5 を使用します。
設定
- 可読性を高めるため、
application.propertiesよりapplication.ymlを使用します。 @ConfigurationPropertiesと@Validated、Bean Validation アノテーションを組み合わせて設定を検証します。- 認証情報をハードコードしないでください。Spring Cloud Config、Vault、または環境変数を使用します。
- 環境を分離するには プロファイル(
spring.profiles.active)を使用します。開発用の設定を本番環境にデプロイしないでください。
並行処理とパフォーマンス
- 仮想スレッドを有効にします:
spring.threads.virtual.enabled=true(Spring Boot 3.3 以降)。 - バックグラウンドタスクには、仮想スレッドエグゼキューターと
@Asyncを使用します。 - バックプレッシャーに対応したリアクティブストリームが必要な場合(大規模なデータセットのストリーミングなど)に限り、Spring WebFlux(Project Reactor)を使用します。標準的な CRUD では、仮想スレッドと WebMVC の組み合わせのほうがシンプルで、パフォーマンスも同等です。
- 負荷の高い読み取り処理には、Redis をバックエンドとする Spring Cache(
@Cacheable、@CacheEvict)を使用します。 - 本番環境では HTTP/2 を有効にします(
server.http2.enabled=true)。
セキュリティ(Spring Security 6 以降)
SecurityFilterChainBean を使用する方法を採用します。WebSecurityConfigurerAdapterの継承は避けてください(Spring Security 6 で削除されています)。- サービスメソッドに
@PreAuthorize("hasRole('...')")を指定してメソッドレベルのセキュリティを適用します。コントローラーレイヤーだけで制御しないでください。 - ブラウザー向けアプリでは CSRF 保護を使用します。JWT を使うステートレス API の場合に限り、無効にします。
- CORS は
@CrossOriginをコントローラーごとに指定するのではなく、CorsConfigurationSourceBean で設定します。 - Spring の
PasswordEncoder(BCryptPasswordEncoderまたはArgon2PasswordEncoder)を使用します。 - JWT のオーディエンス(
aud)と発行者(iss)のクレームを検証します。有効期限は短く設定し(15~60 分)、リフレッシュトークンを使用します。
データアクセス
- 動的クエリには、Spring Data JPA と QueryDSL または Criteria API を使用します。
- 同じクラスの public メソッドに
@Transactionalを付けるのは避けてください(プロキシが迂回されます)。自己インジェクションを使うか、サービスレイヤーを分離してください。 spring.jpa.open-in-view=falseを設定します。トランザクション外で遅延読み込みを行うと、LazyInitializationExceptionが発生します。- 実データベースを使った結合テストには、
@SpringBootTestと Testcontainers を使用します。 - スキーマは Flyway または Liquibase で管理します。自動 DDL は使用しないでください(本番環境では
spring.jpa.hibernate.ddl-auto=validateを設定します)。
可観測性
spring-boot-starter-actuatorとmicrometer-tracing-bridge-otelを含めます。- メトリクスは Prometheus に、トレースは Jaeger/Tempo にエクスポートします。
/actuator/health、/actuator/metrics、/actuator/prometheusを公開します。それ以外の Actuator エンドポイントはすべて保護してください。- Logback と
logstash-logback-encoderを使った構造化ログを使用します。
Python
ベースライン:Python 3.12 以降。新しいプロジェクトでは 3.13 を使用します。すべての箇所で型を適用してください。
プロジェクト構成
src/
app/
api/ # FastAPI routers / Django views
services/ # business logic
models/ # ORM models
schemas/ # Pydantic schemas
core/ # config, security, db
tests/
pyproject.toml
型安全性
- すべての関数とクラス属性に型ヒントを付けます(
def fn(x: int) -> str)。 - CI で
mypy --strictまたはpyrightを実行します。マージ前に型エラーをゼロにします。 - dict の構造には
TypedDictを、データを保持する用途にはdataclassまたは Pydantic モデルを使用します。 - 適切な場合は、ABC の代わりに
Protocolを使って構造的部分型付けを行います。
非同期処理とパフォーマンス
- 非同期 Web サービスには、
FastAPIまたはStarletteとasyncioを使用します。 - I/O 待ちの関数にはすべて
async defを使用します。非同期コンテキストからブロッキング関数を呼び出さないでください。asyncio.run_in_executor()またはanyio.to_thread.run_sync()を使用します。 - 本番環境では
uvicornとgunicorn(複数ワーカー)を使用します。 - 非同期サービス内では
requests(同期)ではなくhttpx(非同期)を使用します。 - CPU のボトルネックのプロファイリングには
py-spyまたはaustinを、メモリーのプロファイリングにはmemrayを使用します。 - 高頻度で使用するクラスには
__slots__を使用し、メモリーのオーバーヘッドを削減します。
セキュリティ
- Pydantic v2 のモデル(
BaseModel、model_validator)を使って、すべての入力を検証します。スキーマ検証と解析の両方に使用できます。 - パスワードには、
argon2またはbcryptとpasslibを使用します。 - JWT の処理には
python-joseまたはPyJWTを使用し、アルゴリズムのホワイトリストを明示的に指定します(algorithms=["RS256"])。 - すべての SQL クエリでパラメーターを使用します。SQL に f-string を使用しないでください。
- CI で静的セキュリティ分析に
banditを使用します。 - 依存関係は
requirements.txtまたはpyproject.tomlで固定します。CI でpip-auditを使用します。 - 信頼できないデータには
pickleを使用しないでください。JSON または MessagePack を使用します。
依存関係と環境の管理
- 依存関係の解決と仮想環境の管理には、
uv(2024年以降の標準)を使用します。 - すべての依存関係をバージョン制約とともに
pyproject.tomlで定義します。uv lockでロックします。 - 本番サーバーにパッケージをグローバルインストールしないでください。必ず仮想環境を使用します。
テスト
- 非同期テストには、
pytestとpytest-asyncioを使用します。 - データ変換ロジックのプロパティベーステストには、
hypothesisを使用します。 - カバレッジ80%以上を達成し、セキュリティ上重要なパスは100%を必須とします。
- テストデータの生成には、
factory_boyまたはpolyfactoryを使用します。
Elixir
基準:Elixir 1.17+、OTP 27+。
基本原則
- BEAMのアクターモデルを活用します。プロセスは低コスト(300~2700バイト)なので、積極的に生成します。
- クラッシュを許容します。正常系を記述し、障害からの回復にはスーパーバイザーを使用します。
- 不変データを優先します。すべての値は不変であり、関数は新しい値を返します。
- 関数のヘッド、case、with、receiveなど、あらゆる場所でパターンマッチングを使用します。
- 読みやすいデータ変換にはパイプライン(
|>)を使用します。
並行処理とOTP
- OTPビヘイビア(
GenServer、GenStateMachine、Supervisor、DynamicSupervisor)を使用して構築します。 - どのプロセスが重要で、どのプロセスが一時的なのかを考慮し、監視ツリーを慎重に設計します。
- 並列処理には、並行数を制限した
Task.async/awaitを使用します。一括処理には、max_concurrencyを指定したTask.async_streamを使用します。 - プロセスの検出には
Registryを、分散プロセスグループにはpgを使用します。 - 1つのプロセスで長時間実行される計算を避けます。スケジューラーがブロックされるためです。ワーカープール(
poolboy、nimble_pool)またはTaskに処理を委譲します。 - バックプレッシャーに対応したデータパイプラインには、
GenStage/Broadwayを使用します。
フォールトトレランス
- 監視戦略:独立したワーカーには
:one_for_one、順序依存のあるワーカーには:rest_for_one、密接に連携するグループには:one_for_allを使用します。 - スーパーバイザーには適切な
max_restartsとmax_secondsを設定します。 - インメモリ共有状態には
:ets(プロセスがクラッシュしても存続)を、読み取りの多いグローバル設定には:persistent_termを使用します。
パフォーマンス
:fprof、eflambe、またはErlang組み込みの:erlang.traceを使用してプロファイリングします。- ホットパスで大きなバイナリを生成するのは避けます。文字列連結ではなく、効率的なパターンマッチングでバイナリを照合します。
- 大規模なコレクションの遅延評価には
Streamを使用します。Enumは即時評価します。 - CPUバウンドのNIFにはRustler(Rust NIF)を使用します。C NIFより安全で、セグメンテーション違反のリスクがありません。
セキュリティ
- レンダリングの前に、すべてのユーザー入力をサニタイズします。
Phoenix.HTML.safe_to_string/html_escapeを使用します。 - パスワードのハッシュ化には
Argon2(argon2_elixir)を使用します。 - シークレットは、環境変数から読み込む
config/runtime.exsに保存します。config.exsには保存しないでください。 - アルゴリズムを固定したJWTには、
guardianまたはjokenを使用します。 - すべての外部データを
Ecto.ChangesetまたはSchematicで検証します。
Phoenix
基準:Phoenix 1.7+、Ecto 3.11+。
アーキテクチャ
- Contextパターンに従います。関連するスキーマ、チェンジセット、クエリをコンテキストモジュール(例:
Accounts、Catalog)にまとめます。 - コントローラーの役割は、パラメーターの解析、コンテキストの呼び出し、レスポンスのレンダリングのみです。コントローラーにビジネスロジックを含めないでください。
- Web向けとプログラム向けの両方で、すべてのデータ検証と変換にチェンジセットを使用します。
- 読み取りと書き込みを分離します。クエリ関数はデータを返し、コマンド関数は
{:ok, result}または{:error, changeset}を返します。
リアルタイム(Phoenix ChannelsとLiveView)
- カスタムJSを書かずにインタラクティブなUIを実現するには、Phoenix LiveViewを使用します(状態を保持するWebSocketベースの仕組みです)。
- LiveViewに適さないマルチプレイヤー/PubSubパターンには、Phoenix Channelsを使用します。
Phoenix.PubSubとRedis、または分散Erlang向けのlibclusterを使用して、ノード間でPubSubをスケールさせます。- LiveViewソケットのassignには、テンプレートで実際にレンダリングするデータだけを保持します。大きなバイナリをソケットに保存しないでください。
パフォーマンス
- Cowboy 2.x で HTTP/2 を有効にします。
- 大規模なデータセットを処理する場合は、Ecto の
Repo.streamを使用します(すべてのレコードをメモリに読み込まずに済みます)。 preloadを明示的に使用し、暗黙的な遅延読み込みには決して頼らないでください(Ecto には遅延読み込みがありません。%Ecto.Association.NotLoaded{}が返されます)。- LiveView では
:cache_storeを、データにはConCache/Cachexを使って、レンダリング済みのフラグメントをキャッシュします。 - メトリクスには、
telemetryイベントと Prometheus エクスポーター(prom_ex)を使用します。
セキュリティ
- 署名付きの有効期限付きトークン(パスワードリセット、メール確認)には
Phoenix.Tokenを使用します。 Routerで CSRF 保護を有効にします(plug :protect_from_forgery)。Plug.Connプラグで厳格な CSP、X-Frame-Options、その他のセキュリティヘッダーを設定します。PlugAttackまたはHammerでレート制限を行います。- すべてのルートパラメーターを検証し、生の
conn.paramsを Ecto 関数に渡さないでください。 Ecto.Changesetを使って、許可するフィールドを明示的にホワイトリスト化します。
Erlang
基準:OTP 27+。
基本原則
- プロセスを中心に考えます。各プロセスには独自のヒープ、GC、メールボックスがあり、真の分離が実現されます。
- 生の
spawnではなく、OTP のビヘイビア(gen_server、gen_statem、supervisor)を使用します。 - メールボックスのリークを防ぐため、タイムアウト付きの防御的な receive を記述します。
- CI で dialyzer(成功型付けによる静的解析)を使用します。実際のバグを検出できます。
- プロパティベーステストには proper または PropEr を使用します。
信頼性
- クラッシュ分離を前提に設計します。あるプロセスのクラッシュが連鎖しないようにし、スーパーバイザーがそのプロセスを再起動します。
- ノード間で ACID が必要な分散型、インメモリ、またはディスクベースのストレージには
:mnesiaを使用します。 - 本番環境へのデプロイには リリース(
rebar3 releaseまたはmix release)を使用します。自己完結型のため、実行時環境のインストールは不要です。 - ホットコードアップグレードにダウンタイムが許されない重要なシステムでは、
appupファイルを使用します。
パフォーマンス
- 文字列操作より バイナリパターンマッチングを優先します。バイナリは効率的ですが、文字の連結リストはそうではありません。
- 大きなメッセージの受け渡しは避け、巨大なデータ構造ではなく参照や pid を送ります。
- スケジューラー数を CPU のトポロジーに合わせて調整します。
:erlang.system_info(:schedulers_online)を使用します。 - 複数のプロセスからロックフリーで並行してインメモリデータにアクセスするには、
etsを使用します。
Rust
基準:Rust 1.80+ (stable)。ツールチェーンの管理には
rustupを使用します。
所有権とメモリー安全性
- 借用チェッカーを理解します。これは正しさを保証するものであり、障害ではありません。借用チェッカーに沿って実装します。
- 構造体では所有データを優先し、可能な場合は関数シグネチャで借用を使用します。
- スレッド間で所有権を共有するには
Arc<T>を使用し、Rc<T>はシングルスレッドのコンテキストでのみ使用します。 - 共有可変状態を保護するには
Mutex<T>/RwLock<T>を使用します。共有状態よりもメッセージ受け渡し(mpsc、tokio::sync::mpsc)を優先します。 unsafeブロックは避けます。必要な場合は分離し、不変条件を文書化して、安全な抽象化でラップします。ResultまたはOptionを返す関数には#[must_use]を使用します。
エラー処理
- 失敗する可能性のあるすべての操作に
Result<T, E>を使用します。本番コードで.unwrap()を使わず、?演算子または明示的な処理を使用します。 - ドメイン固有のエラー列挙型を定義します。ライブラリークレートには
thiserrorを、アプリケーションクレートにはanyhowを使用します。 - コンテキストを付けてエラーを伝播します:
ctx_err.context("while reading config")。
非同期(Tokio)
- ネットワークサービスの非同期ランタイムには Tokio を使用します。特定のユースケースに限り
async_stdを使用します。 - 独立した非同期タスクには
tokio::spawnを使用します。複数のタスクの管理にはJoinSetを使用します。 - 非同期コンテキストでのブロッキング呼び出しは避けます。CPU 負荷の高い処理やブロッキング I/O には
tokio::task::spawn_blockingを使用します。 - HTTP サービスには
towerミドルウェアスタック(タイムアウト、再試行、負荷遮断、レート制限)を使用します。 - HTTP API には
axumまたはactix-webを使用します。どちらも本番環境で使用できる品質です。
パフォーマンス
- ゼロコスト抽象化:イテレーター、ジェネリクス、トレイトは効率的なコードにコンパイルされます。
- プロファイリングには
cargo flamegraphまたはperfを使用します。マイクロベンチマークにはcriterionを使用します。 - スタック割り当てを優先します。ヒープや動的ディスパッチが必要な場合にのみ Box を使用します。
- ネットワークバッファーを低コストで複製するには、
bytes::Bytes(参照カウント方式)を使用します。 - 最大限に最適化するには、リリースプロファイルで LTO(
lto = true)とcodegen-units = 1を有効にします。
セキュリティ
- 依存関係に既知の CVE がないか確認するため、CI で
cargo auditを使用します。 - ライセンスと重複した依存関係のポリシーを適用するには、
cargo denyを使用します。 - パーサーコードには、
cargo +nightly fuzz(libFuzzer ベース)を使用してファジングを行います。 - 文字列フォーマットを使って SQL やシェルコマンドを構築してはいけません。
Go(Golang)
基準:Go 1.23 以降(最新の安定版を使用してください。2026 年初頭時点では Go 1.24 です)。
プロジェクトの構成
標準的な Go プロジェクトの構成に従います。
cmd/ # main packages (one per binary)
internal/ # private packages (not importable externally)
pkg/ # public reusable packages
api/ # OpenAPI/proto definitions
- カプセル化を徹底するため、
internal/を積極的に使用します。
Go らしい書き方
- エラーは値です。
(T, error)を返します。例外はないため、すべてのエラーを明示的に確認します。 - エラーを調べるには
errors.Is()とerrors.As()を使用します。fmt.Errorf("ctx: %w", err)でエラーをラップします。 - I/O、RPC、またはキャンセルの可能性があるすべての関数では、
context.Contextを第 1 引数として使用します。 - デッドライン、キャンセル、リクエストスコープの値には
contextパッケージを使用します。ゴルーチンローカルの状態は使用しないでください。 - 小さなインターフェースを優先します。最適なインターフェースはメソッドが 1~3 個です。インターフェースを受け取り、具体型を返します。
- リソースのクリーンアップ(クローズ、ロック解除)には
deferを使用します。必ずdefer resp.Body.Close()を呼び出します。
並行処理
- ゴルーチンは低コストです(約 2 KB)。リクエストやタスクごとに起動します。
- ゴルーチンリークを防ぐため、ゴルーチンには必ず done チャネルまたは
sync.WaitGroupを組み合わせます。 - 通信にはチャネルを使用し、チャネルでは扱いにくい場合に限り、共有状態の保護に
sync.Mutexを使用します。 - エラーの伝播を伴うゴルーチンのグループ管理には
errgroup(golang.org/x/sync/errgroup)を使用します。 - データ競合を検出するには、
go test -raceでテストを実行します。データ競合は未定義の動作を引き起こすため、すべて修正します。
パフォーマンス
- CPU、メモリ、ゴルーチン、ミューテックスのプロファイリングには
pprof(net/http/pprof)を使用します。 - 割り当てコストの高いオブジェクト(バイトバッファー)の再利用には
sync.Poolを使用します。 - 容量がわかっているスライスやマップは、事前に割り当てます:
make([]T, 0, n)、make(map[K]V, n)。 - 文字列やバイト列の蓄積には
strings.Builderとbytes.Bufferを使用します。 go test -benchでベンチマークを実行します。結果の比較にはbenchstatを使用します。
セキュリティ
database/sqlのプリペアドステートメントですべての SQL を安全に扱います。生の文字列クエリよりもpgxまたはsqlcを使用します。- 入力の検証には
go-playground/validatorまたはgo-ozzo-validationを使用します。 - 乱数値には
crypto/randを使用し、math/randは決して使用しません。 - パスワードには
golang.org/x/crypto/argon2またはbcryptを使用します。 - すべての HTTP クライアントとサーバーにタイムアウト(
ReadTimeout、WriteTimeout、IdleTimeout)を設定します。 - CI で
govulncheckとstaticcheckを実行します。
React
基準:React 19。常に TypeScript と併用してください。
コンポーネント設計
- 単一責任:1 つのコンポーネントは 1 つのことだけを行います。約 150 行を超えたらコンポーネントを切り出します。
- hooks を使用する関数コンポーネントを優先します。クラスコンポーネントは使用しません。
- 深くネストした prop の受け渡しよりもコンポジションを優先します。状態は必要な範囲でのみ上位に持ち上げます。
- 柔軟で再利用可能な UI プリミティブには、複合コンポーネントとレンダープロップを使用します。
- コンポーネント、スタイル、テストは同じディレクトリに配置します。
状態管理
- ローカルの UI 状態:
useState、useReducer。 - 共有状態/サーバー状態:**React Query(TanStack Query)**または SWR。リモートデータには Redux を使用しません。
- グローバルなクライアント状態:軽量な Zustand またはアトミックな Jotai を使用します。複雑な状態マシンがある場合を除き、Redux は避けます。
- 緊急性の低い状態更新には
useTransitionとuseDeferredValueを使用し、UI の応答性を保ちます。
パフォーマンス
- メモ化は必要最小限にし、正しく使います。高コストな計算には
useMemo、メモ化された子コンポーネントに渡す関数参照を安定させるにはuseCallback、高コストな純粋コンポーネントにはReact.memoを使います。 - リストでは
keyプロパティを正しく使います。安定した ID を使い、配列のインデックスは使わないでください(調整時のバグの原因になります)。 - コード分割には
Suspenseとlazy()を使います。最低限、ルートの境界で分割してください。 - 頻繁に再レンダリングされるコンポーネントでは、JSX のレンダリングメソッド内で無名関数を作成しないでください。
- SSR に対応した安定した ID には
useId()を使います。 - レンダリングを最適化する前に、React DevTools Profiler でプロファイリングしてください。
アクセシビリティ
- アクションには
<button>、ナビゲーションには<a>を使います。クリック可能な<div>は使わないでください。 - すべての画像に
alt属性を設定します。コンテンツ画像には説明を記述し、装飾画像にはalt=""を設定します。 - モーダルの開閉時やルート遷移時は、フォーカスを明示的に管理します。
- 動的なコンテンツの更新(トースト、ステータスメッセージなど)には
aria-live領域を使います。 useId()を使って、<label>とフォーム入力を確実に関連付けます。@testing-library/reactでテストします(DOM 構造ではなく、アクセシブルなロールやラベルで要素を検索します)。
セキュリティ
- サニタイズされていないデータに
dangerouslySetInnerHTMLを使わないでください。 - 認証トークンを
localStorageに保存しないでください。HttpOnlyCookie を使います。 eval()やnew Function()は避けてください。- UX のためにクライアント側でフォームデータを検証し、必ずサーバー側でも再検証してください。
Vue
基準:Vue 3.5+ と Composition API、および
<script setup>を使用します。TypeScript は必須です。
Composition API
- すべてのコンポーネントで
<script setup>を使います。コードが簡潔になり、型推論も向上します。 - コンポーザブルは
src/composables/に整理します。それぞれを、用途を絞った再利用可能なリアクティブロジックの単位にします。 - 型安全な props とイベントを定義するため、TypeScript のジェネリクスを使って
defineProps<{}>()とdefineEmits<{}>()を使用します。 - 双方向バインディングのコンポーザブルには
defineModel()(Vue 3.4+)を使います。手動で emit と prop を組み合わせるパターンの代わりになります。
リアクティビティ
- プリミティブには
ref()、オブジェクトにはreactive()を使います(ただし、分割代入するとリアクティビティが失われる点に注意してください)。 - 派生状態には
computed()を使います。値はキャッシュされ、遅延評価されます。 - 複数のリアクティブなソースに自動的に依存する副作用には
watchEffect()を使います。 - 古い値と新しい値が必要な場合や、遅延実行/即時実行を制御する場合は
watch()を使います。 - props を直接変更しないでください。 イベントを発行するか、
defineModel()を使います。
パフォーマンス
- データが安定している繰り返しテンプレートには
v-memoを使います。 - 深いリアクティビティが不要な大きなオブジェクトには
shallowRef()とshallowReactive()を使います。 - 長いリストは仮想化します。
vue-virtual-scrollerまたはtanstack-virtualを使います。 - 重いコンポーネントの遅延読み込みには
defineAsyncComponent()を使います。 v-ifとv-forは別々の要素に設定します。v-ifが優先され、v-forの想定が崩れるためです。
状態管理
- Pinia が公式の標準です。新規プロジェクトでは Vuex を使わないでください。
- ストアの用途を絞ります。ドメインエンティティまたは機能ごとに 1 つのストアを作成します。
- リアクティビティを失わずにストアの状態を分割代入するには、
storeToRefs()を使います。 - 非同期処理にはストアのアクションを使い、ゲッターは純粋に保ちます。
アクセシビリティ
- React のアクセシビリティに関するルールと同じです。Vue に特別な例外はありません。
- コンポーネントライブラリを構築する際は、props から ARIA 属性を動的に展開するために
v-bindを使います。
Nuxt
基準:Nuxt 4(または安定版の Nuxt 3.15+)。Vue 3 と Nitro サーバーエンジンを使用します。
プロジェクト構造(Nuxt 4 srcDir: 'app/')
app/
components/
composables/
layouts/
middleware/
pages/
plugins/
stores/
server/
api/
middleware/
routes/
utils/
public/
nuxt.config.ts
レンダリング戦略
- ルートごとに選択します。クライアントのみの場合は
definePageMeta({ ssr: false })を使います。デフォルトは SSR です。 - ハイドレーションに対応した SSR 可能なデータ取得には、ページ内で
useFetch/useAsyncDataを使います。 - サーバールートやイベントハンドラーでは、
$fetchを直接使います(クライアント側のオーバーヘッドはありません)。 - SSR のコンテキストでクライアント専用コードを混在させないでください。
<ClientOnly>で囲むか、process.clientガードを使います。
パフォーマンス
- 画像を自動で最適化するには、
nuxt/imageを使用します。 - FOIT のないセルフホストフォントには、
nuxt/fontsを使用します。 - Nitro で ISR(インクリメンタル静的再生成)を有効にします:
routeRules: { '/blog/**': { isr: 60 } }。 - プログラムによるナビゲーションには
useNuxtApp().$routerを使用します。Vue Router を直接インポートしないでください。 - スムーズなページ遷移のため、
experimental.viewTransition: trueを設定します。
セキュリティ
- セキュリティヘッダー、レート制限、CSRF を自動で設定するには、Nuxt Security モジュール(
nuxt-security)を使用します。 - サーバー専用の環境変数をクライアントに公開しないでください。サーバー専用の
runtimeConfig.secretKeyと、クライアントから安全に使用できるruntimeConfig.public.apiUrlを使い分けます。 server/api/のすべての入力を、Zod または H3 のgetValidatedBodyで検証します。- 認証用 Cookie には、
httpOnly: true, secure: true, sameSite: 'strict'を指定したuseCookieを使用します。
サーバールート(Nitro)
- API エンドポイントには
server/api/を使用します。グローバルなサーバーミドルウェアにはserver/middleware/を使用します。 - H3 のユーティリティ(
readBody、getQuery、setHeader)とともにdefineEventHandlerを使用します。 - すべてのハンドラーで入力を検証します:
const body = await readValidatedBody(event, schema.parse)。 - KV、キャッシュ、セッションのバックエンドには、Nitro 組み込みのストレージ(
useStorage)を使用します。
Astro
基準:Astro 5+。コンテンツ中心の、アイランドアーキテクチャです。
基本原則
- デフォルトでは JavaScript をゼロにします。 HTML と CSS を配信し、
client:*ディレクティブを使う場合にのみ JavaScript を追加します。 - マーケティングサイト、ドキュメント、ブログなど、コンテンツの多いサイトには Astro を使用します。インタラクティブなアイランドには React/Vue/Svelte を組み合わせます。
- サーバーファーストにします。ほとんどのロジックはブラウザーではなく、ビルド時またはサーバー上で実行します。
アイランドアーキテクチャ
client:loadの使用は控えめにし、ファーストビューのインタラクティブなコンポーネントにのみ使用します。- 重要度の低い UI には、ブラウザーがアイドル状態になってから読み込む
client:idleを優先します。 - ファーストビューより下のコンポーネントには、スクロールして表示範囲に入ったときに読み込む
client:visibleを使用します。 - 認証状態に依存する UI など、SSR を行わないコンポーネントには
client:only="react"を使用します。
コンテンツコレクション
src/content/config.tsで Zod を使ってスキーマを定義します。コンテンツの型安全性が保証されます。- コンテンツファイルには、生の
import.meta.globではなく、getCollection()とgetEntry()を使用します。 - 自動で Astro Image 最適化を行えるよう、コンテンツ画像を同じディレクトリに配置します。
パフォーマンス
- すべての画像に
astro:assetsの<Image>を使用します。WebP 変換、サイズ調整、遅延読み込みが自動で行われます。 - CDN のキャッシュ効率を最大化するには、静的出力(
output: 'static')を優先します。 - 動的ルートにのみ、
output: 'server'またはoutput: 'hybrid'を使用します。 - コンテンツ処理を高速化するには、
experimental.contentLayerを有効にします。 - Astro のサーバーアダプター(Vercel、Netlify、Node)を使って、再検証機能を備えた API 連携ページを事前レンダリングします。
セキュリティ
- サーバーでレンダリングするルートの認証には、Astro ミドルウェア(
src/middleware.ts)を使用します。 - Astro コンポーネントでプライベートな環境変数を公開しないでください。
import.meta.env.SECRET_KEYはserver.ts/.server.tsファイル内でのみ使用します。 - サーバーアダプターの設定または CDN の WAF で、セキュリティヘッダーを設定します。
SQL / NoSQL
あらゆるデータベースに共通する原則
- スキーマのマイグレーション:必ずバージョン管理されたマイグレーションツール(Flyway、Liquibase、Alembic、Ecto migrations、golang-migrate)を使用します。本番環境で手動の DDL を実行しないでください。
- ゼロダウンタイムデプロイを行う場合、すべてのマイグレーションは後方互換性を保つ必要があります(古いカラムを削除する前に新しいカラムを追加し、段階的に拡張してから縮小します)。
- コネクションプーリングを使用します:PgBouncer(PostgreSQL)、ProxySQL(MySQL/MariaDB)。CPU とサービスの種類に応じてプールのサイズを設定します。
- クエリの暴走によるブロックを防ぐため、すべての DB 接続に
statement_timeoutとlock_timeoutを設定します。 - 監査可能なデータには論理削除(
deleted_at TIMESTAMP)を実装します。一時的なデータであれば、物理削除でも問題ありません。 - すべてのタイムスタンプには UTC を使用します。
TIMESTAMPTZ(PostgreSQL)または、UTC を明示的に扱うDATETIMEとして保存します。
PostgreSQL のベストプラクティス
TIMESTAMPではなくTIMESTAMPTZを使用してください。分散環境で使う主キーにはUUIDを使用してください。- 外部キーを定義してください。デフォルトでは
ON DELETE RESTRICTを使用し、CASCADEは意図する場合に限って検討してください。 - 外部キー列にインデックスを作成してください。定期的に
EXPLAIN (ANALYSE, BUFFERS)でクエリプランを分析してください。 - よく使うフィルター付きクエリには部分インデックスを使用してください:
CREATE INDEX ON orders (user_id) WHERE status = 'pending'。 - カバリングインデックス(
INCLUDE)を使用して、頻繁に読み取られる処理でのヒープフェッチを回避してください。 - 半構造化データには
JSONよりJSONBを優先してください(インデックス化され、バイナリー形式で解析されます)。 - アプリケーションのクエリで
SELECT *を避けてください。常に列を明示して選択してください。 - 一括インポートには
COPYを使用してください。1 行ずつINSERTするより 10~100 倍高速です。 - 遅いクエリを特定するために
pg_stat_statementsを有効にしてください。定期的にVACUUM ANALYSEを実行してください(または autovacuum が適切に調整されていることを確認してください)。 - マルチテナントでは、テナント数が中程度で強い分離が必要な場合はテナントごとのスキーマを、高規模 SaaS では**行レベルセキュリティ(RLS)**を使用してください。
MySQL / MariaDB のベストプラクティス
InnoDBエンジンのみを使用してください。新しいテーブルで MyISAM を使用しないでください。- すべての箇所で
utf8mb4文字セットとutf8mb4_unicode_ci照合順序を使用してください。 - 自動採番の主キーには
BIGINT UNSIGNEDを優先してください。大規模運用ではサイズが重要です。 innodb_buffer_pool_sizeを、専用 DB サーバーの RAM の 70~80% に設定してください。コンテナーの RAM 上限に近づけないでください。- クエリ分析には
EXPLAIN FORMAT=JSONを使用してください。 - 複雑なビジネスロジックにはストアドプロシージャを使用せず、ロジックはアプリケーションコードに記述してください。
MongoDB のベストプラクティス
- まずスキーマを設計してください。リレーショナルな正規化ではなく、データへのアクセスパターンに合わせてデータをモデル化してください。
- スキーマを適用するため、コレクションレベルで検証ルール(
$jsonSchema)を使用してください。 - クエリの述語とソート対象のフィールドには必ずインデックスを作成してください。
explain("executionStats")で検証してください。 - 耐久性のために
writeConcern: { w: "majority" }を使用してください。強い整合性の読み取りにはreadConcern: "majority"を使用してください。 - ドキュメント間の原子性を確保するにはトランザクション(複数ドキュメント、レプリカセットが必要)を使用してください。
- セルフホスト型のデプロイでは Atlas を使用するか、レプリカセットを有効にしてください。スタンドアロンの MongoDB は本番環境向けではありません。
- ドキュメントに上限のない配列を埋め込まないでください。配列が際限なく増える可能性がある場合は、参照を使用してください。
$lookupは控えめに使用してください。これはスキーマ設計に問題がある可能性を示します。頻繁に読み取られる処理には、事前に結合したドキュメントを優先してください。
Redis / Valkey のベストプラクティス
- Redis(または Valkey 7 以降)は、キャッシュ、セッションストア、Pub/Sub ブローカーとして使用し、プライマリデータベースとしては使用しないでください。
- キャッシュキーには必ず
TTLを設定してください。意図的な場合を除き、有効期限のないデータを保存しないでください。 - 本番環境の HA には Redis Cluster または Sentinel を使用してください。単一ノードの Redis は耐障害性がありません。
- 読み取り・変更・書き込みの操作をアトミックに行うには、
MULTI/EXECトランザクションまたはLua スクリプトを使用してください。 - キーの名前空間を明確に分けてください:
{service}:{entity}:{id}(例:auth:session:uuid)。 - 本番環境では
requirepassと TLS で保護してください。内部ネットワークのみにバインドし、Redis を公開しないでください。 - 本番環境には Valkey
9.0.xを使用してください(2025 年時点で 9.1 は RC に移行しました)。
キー・バリューおよび時系列データ
- DynamoDB:シングルテーブル設計でモデル化し、キーを選ぶ前にアクセスパターンを定義してください。
- Cassandra:書き込みの多い時系列ワークロード向けに設計し、クエリごとに非正規化してください。
- InfluxDB / TimescaleDB:メトリクス/テレメトリデータに使用してください。時間でパーティション分割し、データ保持ポリシーを設定してください。
クエリとアクセスパターン
- CRUD には ORM/クエリビルダーを、複雑な分析やパフォーマンスが重要なクエリには生の SQL を使用してください。
- 文字列補間で SQL を生成しないでください。パラメーター化クエリまたは ORM の抽象化を使用してください。
EXPLAIN ANALYSEで遅いクエリを分析して最適化してください。プロファイリング後にインデックスを追加し、先回りした最適化は避けてください。- 保存データ内の PII や金融データには、データベースレベルの列暗号化(
pgcrypto、MongoDB FLE、MySQL AES 関数)を適用してください。
分野横断的なチェックリスト
マージ前チェックリスト(すべての PR)
- すべてのエントリーポイントで入力を検証する
- コードやログにシークレットを含めない
- エラーを処理し、構造化して返す(決して握りつぶさない)
- ビジネスロジックにはユニットテスト、DB/外部呼び出しには統合テストを用意する
- N+1 クエリを新たに発生させない
- 新しいエンドポイントを文書化する(OpenAPI/AsyncAPI)
- アクセシビリティ:UI の変更では、セマンティック HTML、ARIA、キーボード操作を確認する
-
npm audit/cargo audit/pip-auditで問題がないこと - データベースのマイグレーションに後方互換性があること
- 設定値をハードコードしない(環境変数を使用する)
本番環境へのデプロイ前チェックリスト
- すべてのエンドポイントで TLS 1.3 を必須にする
- すべての公開エンドポイントにレート制限を設ける
- ヘルスチェックとレディネスのエンドポイントが正しいステータスを返す
- すべてのサービスを通じて相関 ID が伝播する構造化ログを設定する
- メトリクスをエクスポートする(Prometheus/OpenTelemetry)
- SLO のバーンレートに対するアラートを定義する
- 開発/ステージング環境の値からシークレットをローテーションする
- データベース接続プーリングを設定し、適切なサイズにする
- バックアップと復元の手順をテストする
- 各サービスのランブックを文書化する
ライセンス
MIT License
Copyright (c) 2026 Patrick Aziken / Upperloft Creations Limited
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
バージョン 2026.1.0 — 2026 年 5 月、Upperloft Creations Limited によりリリース。
四半期ごとにレビューしてください。未解決の問題は https://github.com/skylarng89/engineering-best-practices-skill/issues で確認できます。