0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

#0145(2025/05/22)Code First vs Schema First

Last updated at Posted at 2025-05-22

Code First vs Schema First

1. はじめに

ソフトウェア設計では「Code First」と「Schema First」という2つの開発スタイルが広く使われています。どちらを選ぶかで、チームのコミュニケーション方法や保守コスト、開発スピードは大きく変わります。本稿では GraphQL API と データベース ORM を題材に、両者の概念・利点・欠点を3000文字程度で整理し、サンプルコードを交えて実践的に解説します。

2. Code First とは

Code First は「まずコードを書く」アプローチです。開発者はクラスや型定義など実装側のコードを起点にし、ツールを使ってスキーマやマイグレーションを自動生成します。

  • 実装担当者が主導権を握りやすい
  • IDE 補完が効くため生産性が高い
  • コードと型が 1 箇所に集約され、重複が少ない

ただし、生成物であるスキーマがブラックボックス化しやすく、非エンジニアが参照しづらい点が課題です。

3. Schema First とは

Schema First は「まずスキーマを書く」アプローチです。API 仕様書や ER 図、SDL (Schema Definition Language) をチームで合意し、その定義に沿って実装を進めます。

  • 仕様が明文化されるのでチーム間で共有しやすい
  • 設計レビューや契約駆動開発 (Contract‑Driven Development) に向く
  • フロントエンドとバックエンドを並行開発しやすい

一方で、実装コードとスキーマを二重管理するため同期ズレが起きやすく、手間も増えがちです。

4. メリット・デメリット比較

観点 Code First Schema First
開発速度 IDE 補完により高速 合意形成後は並行開発が高速
ドキュメンテーション 自動生成だとやや不透明 スキーマがそのまま仕様書
型の重複 少ない 多くなりがち
変更フロー 実装主導 仕様主導
学習コスト 実装者は低い デザイナ・QA も参画しやすい

5. ケーススタディ

5‑1. GraphQL API

Code First (TypeScript + type‑graphql)

import { ObjectType, Field, Int } from "type-graphql";

@ObjectType()
export class User {
  @Field()
  name!: string;

  @Field(type => Int)
  age!: number;
}

上記クラスから、下記のような GraphQL SDL が自動生成されます。

type User {
  name: String!
  age: Int!
}

Schema First (SDL + Apollo Server)

# schema.graphql
type Query {
  user(id: ID!): User!
}

type User {
  id: ID!
  name: String!
  age: Int!
}
// resolver.ts
import { Resolvers } from "./generated/graphql";
export const resolvers: Resolvers = {
  Query: {
    user: (_, { id }) => fetchUserFromDB(id),
  },
};

SDL を中心にリゾルバを実装する流れになります。

5‑2. データベース ORM

Code First (Python + SQLAlchemy)

from sqlalchemy import Column, Integer, String
from sqlalchemy.orm import declarative_base

Base = declarative_base()

class User(Base):
    __tablename__ = "users"
    id = Column(Integer, primary_key=True)
    name = Column(String, nullable=False)
    age = Column(Integer)

Alembic などを通してマイグレーションファイルが生成されます。

Schema First (SQL + Alembic)

-- 001_create_users.sql
CREATE TABLE users (
  id SERIAL PRIMARY KEY,
  name VARCHAR(255) NOT NULL,
  age INT
);
# models.py (SQLAlchemy のみ同期定義)
class User(Base):
    __tablename__ = "users"
    id = Column(Integer, primary_key=True)
    name = Column(String, nullable=False)
    age = Column(Integer)

DDL → コードの順に書くため、既存 DB のリバースエンジニアリング案件にも適します。

6. どちらを選ぶべきか?

チーム状況 推奨アプローチ
MVP/Fast‑Prototyping、小規模 Code First
ドメインが複雑、コンシューマが多い Schema First
コンサル・SIで外部契約がある Schema First
モノリス→マイクロサービス移行期 Code First で局所的に試し、最終的に Schema First へ移行

判断チェックリスト

  • 仕様を非エンジニアと共有したい? → Schema First
  • とにかく早く動く物がほしい? → Code First
  • 既存 DB を再利用するか? → Schema First
  • 型安全を保ったまま変更頻度が高い? → Code First

7. まとめ

Code First と Schema First は対立概念ではなく、プロジェクトのフェーズやチーム構成に応じて使い分けるべきツールです。初期は Code First で爆速開発し、API が安定したら Schema First に切り替えて公開契約を強化する、といったハイブリッド戦略も有効です。要件の変化に合わせ、最適なアプローチを選択しましょう。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?