mcpField
S
sdk-dx

sdk-dx

github.com/jonathimer開発87115 回インストール34 週間前に更新
リポジトリ

sdk-dx について

SDK の設計者向けに、API 設計、エラー処理、型安全性、IDE 対応を案内する開発者体験スキルです。バージョン管理、移行ガイド、リリース前の確認項目も扱います。

主な機能

  1. 01一般的な用途を簡潔にし複雑さを段階的に提示
  2. 02明確で対処方法が分かるエラーメッセージの設計
  3. 03型安全性と IDE の自動補完への対応
  4. 04セマンティックバージョニングと非推奨化の計画
  5. 05移行ガイドと品質チェックリストの作成

活用シーン

  1. 01使いやすい SDK API の設計
  2. 02SDK のエラーメッセージの改善
  3. 03破壊的変更とバージョン更新の計画
  4. 04SDK のリリース準備状況の確認

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/jonathimer/devmarketing-skills --skill sdk-dx

インストール後、Claude Code で/sdk-dxを入力して読み込まれたか確認します。

同梱ファイルREADME.md

詳細

SDK の設計と開発者エクスペリエンス

最も効果的な SDK のマーケティングは、開発者が話題にせずにはいられない SDK を作ることです。SDK によって開発者が生産的で有能だと感じれば、開発者はあなたの支持者になります。反対に、使いづらさを感じさせてしまえば、どれだけマーケティングに力を入れても挽回できません。

概要

SDK の開発者エクスペリエンス(DX)とは、開発者がライブラリを使うときに感じるあらゆることを指します。

  • 見つけやすさ:どれほど簡単に見つけてインストールできますか?
  • 学びやすさ:使い方をどれほど早く理解できますか?
  • 使いやすさ:日々の作業でどれほど生産的に使えますか?
  • デバッグのしやすさ:問題をどれほど簡単に解決できますか?
  • アップグレードのしやすさ:新しいバージョンをどれほど負担なく導入できますか?

優れた SDK の DX は競争上の優位性になります。開発者は、自分を賢く感じさせてくれるツールを選びます。

始める前に

developer-audience-context スキルを確認し、次の点を把握してください。

  • 対象とする開発者はどの言語やフレームワークを使っていますか?
  • 最も一般的な IDE/エディター環境は何ですか?
  • 対象分野における開発者の経験レベルはどの程度ですか?
  • 競合する SDK を使ったことはありますか?どのような点を好み、または好まないのでしょうか?

SDK の設計上の判断は、ユーザーへの深い理解に基づいて行う必要があります。

API 設計の原則

原則 1:一般的なユースケースを最適化する

最も頻繁に使われるユースケースでは、必要なコードを最小限にします。

良い設計:

# Common case: send a simple message
client.messages.send("Hello world", to="+1234567890")

# Full control when needed
client.messages.send(
    body="Hello world",
    to="+1234567890",
    from_="+0987654321",
    status_callback="https://...",
    media_urls=["https://..."]
)

悪い設計:

# Every call requires full configuration
message = Message(
    body="Hello world",
    to=PhoneNumber("+1234567890"),
    from_=PhoneNumber(config.get_default_from()),
    options=MessageOptions(
        status_callback=None,
        media_urls=[]
    )
)
client.messages.send(message)
原則 2:段階的な情報開示

シンプルな使い方から始め、必要に応じて複雑な機能を使えるようにします。

// Level 1: Simplest possible usage
const result = await client.analyze("Hello world");

// Level 2: Common options
const result = await client.analyze("Hello world", {
  language: "en",
  features: ["sentiment", "entities"]
});

// Level 3: Full control
const result = await client.analyze("Hello world", {
  language: "en",
  features: ["sentiment", "entities"],
  model: "v2-large",
  timeout: 30000,
  retries: { max: 3, backoff: "exponential" }
});
原則 3:早期に、明確に失敗させる

実行可能な解決策を示すメッセージとともに、できるだけ早い段階でエラーを検出します。

良い例:

# Validation at construction time
client = MyClient(api_key="")
# Raises immediately: ValueError: API key cannot be empty.
# Get your API key at https://dashboard.example.com/keys

# Clear error at runtime
client.users.get("invalid-id")
# Raises: NotFoundError: User 'invalid-id' not found.
# Use client.users.list() to see available users.

悪い例:

client = MyClient(api_key="")  # No validation
result = client.users.get("invalid-id")
# Returns: None (is this an error? empty result? who knows?)
# Or worse: raises generic Exception with stack trace
原則 4:適切なデフォルト値

設定しなくても、ほとんどのケースで使えるデフォルト値にします。

// This should just work without configuration
const client = new MyClient({ apiKey: process.env.MY_API_KEY });

// Sensible defaults:
// - Automatic retries with exponential backoff
// - Reasonable timeouts
// - JSON content type
// - Standard auth headers
// - Connection pooling

問題解決につながるエラーメッセージ

エラーメッセージはドキュメントです。役立つ内容にしましょう。

エラーメッセージのフレームワーク

すべてのエラーメッセージで、次の点を説明します。

  1. 何が起きましたか?
  2. なぜ起きましたか?
  3. どうすれば解決できますか?
良いエラーメッセージと悪いエラーメッセージ

良い例:

AuthenticationError: Invalid API key provided.

The API key 'sk_test_abc...' (test key) cannot be used for
production requests.

To fix this:
1. Go to https://dashboard.example.com/keys
2. Copy your production API key (starts with 'sk_live_')
3. Update your environment variable: MY_API_KEY=sk_live_...

Docs: https://docs.example.com/authentication

悪い例:

Error: 401 Unauthorized
区別すべきエラーの種類

開発者が捕捉できる、具体的なエラー型を作成します。

from myapi.errors import (
    AuthenticationError,  # Invalid/missing credentials
    AuthorizationError,   # Valid creds, insufficient permissions
    ValidationError,      # Invalid input data
    NotFoundError,        # Resource doesn't exist
    RateLimitError,       # Too many requests
    ServerError,          # Our fault, retry might help
)

try:
    client.users.get(user_id)
except NotFoundError as e:
    # Handle missing user specifically
except AuthenticationError as e:
    # Handle auth issues specifically
except MyAPIError as e:
    # Catch-all for other API errors
エラーにコンテキストを含める
// Bad: generic error
throw new Error("Invalid parameter");

// Good: contextual error
throw new ValidationError({
  message: "Invalid phone number format",
  field: "to",
  value: "+1abc",
  expected: "E.164 format (e.g., +14155551234)",
  docs: "https://docs.example.com/phone-numbers"
});

型安全性

型安全性は、古くならないドキュメントです。

TypeScript のベストプラクティス
// Define explicit types for all inputs and outputs
interface User {
  id: string;
  email: string;
  name: string;
  createdAt: Date;
  metadata?: Record<string, unknown>;
}

interface CreateUserInput {
  email: string;
  name: string;
  metadata?: Record<string, unknown>;
}

// Return types are explicit
async function createUser(input: CreateUserInput): Promise<User> {
  // ...
}

// Use discriminated unions for responses
type ApiResponse<T> =
  | { success: true; data: T }
  | { success: false; error: ApiError };
オートコンプリートを前提とした設計

IDE のオートコンプリートを活用できるように設計します。

// Good: autocomplete shows all options
client.messages.create({
  to: "+1...",     // IDE shows: (property) to: string
  body: "...",    // IDE shows: (property) body: string
  // User types 'me' and sees 'mediaUrls' autocomplete
});

// Bad: requires memorization
client.send("messages", { /* what goes here? */ });
Enum とリテラル型
// Good: constrained values with autocomplete
type MessageStatus = "queued" | "sending" | "sent" | "failed";

interface Message {
  status: MessageStatus;  // IDE shows valid values
}

// Bad: any string accepted
interface Message {
  status: string;  // No guidance, errors at runtime
}

IDE との統合

見つけやすくする

IDE の機能が開発者を支援できるよう、SDK を構成します。

// Namespace methods logically
client.users.get(id)
client.users.list()
client.users.create(data)
client.users.update(id, data)
client.users.delete(id)

// After typing 'client.users.' the IDE shows all user operations
あらゆる場所に JSDoc/Docstring を追加する
/**
 * Creates a new user in your organization.
 *
 * @param input - The user details
 * @param input.email - Must be a valid email address
 * @param input.name - Display name (max 100 characters)
 * @returns The created user with generated ID
 * @throws {ValidationError} If email format is invalid
 * @throws {ConflictError} If email already exists
 *
 * @example
 * const user = await client.users.create({
 *   email: "[email protected]",
 *   name: "Jane Developer"
 * });
 */
async createUser(input: CreateUserInput): Promise<User>
インラインの例
def send_message(self, body: str, to: str, **kwargs) -> Message:
    """
    Send an SMS message.

    Args:
        body: The message content (max 1600 characters)
        to: Recipient phone number in E.164 format

    Returns:
        Message object with ID and status

    Example:
        >>> message = client.messages.send(
        ...     body="Hello from Python!",
        ...     to="+14155551234"
        ... )
        >>> print(message.status)
        'queued'
    """

バージョニング戦略

セマンティックバージョニング

semver を厳守します。

  • MAJOR:破壊的変更(削除、シグネチャの変更)
  • MINOR:新機能(後方互換性あり)
  • PATCH:バグ修正(後方互換性あり)
破壊的変更に該当するもの

破壊的変更(メジャーバージョンの更新が必要):

  • 公開メソッドまたはプロパティの削除
  • メソッドシグネチャの変更
  • 戻り値の型の変更
  • デフォルトの動作の変更
  • 言語/ランタイムのバージョンへの対応の終了

破壊的変更ではないもの(マイナーまたはパッチ):

  • 新しいメソッドの追加
  • オプションのパラメーターの追加
  • 機能の非推奨化(削除はしない)
  • 誤った動作を変更するバグ修正
非推奨化のプロセス
import warnings

def old_method(self):
    """
    .. deprecated:: 2.3.0
       Use :meth:`new_method` instead. Will be removed in 3.0.0.
    """
    warnings.warn(
        "old_method() is deprecated, use new_method() instead. "
        "See migration guide: https://docs.example.com/migrate-v3",
        DeprecationWarning,
        stacklevel=2
    )
    return self.new_method()

移行ガイド

移行ガイドの構成
# Migrating from v2 to v3

## Overview
Version 3 introduces [major change] and removes [deprecated feature].
Migration typically takes [time estimate].

## Breaking Changes

### 1. Client Initialization
**Before (v2):**
```python
client = MyClient(key="...")

変更後(v3):

client = MyClient(api_key="...")

理由:他の SDK パラメーターとの一貫性を保つためです。

2.[次の破壊的変更]

...

削除された非推奨機能

  • client.old_method() - 代わりに client.new_method() を使用してください
  • LegacyClass - 代わりに ModernClass を使用してください

新機能

-[移行する価値のある機能]

サポートが必要ですか?

-[移行サポートの連絡先] -[移行に関する質問の相談時間]


### Codemods and Automation

When possible, provide automated migration:

```bash
# Provide migration scripts
npx @myapi/migrate-v3

# Or codemods
npx jscodeshift -t @myapi/codemods/v2-to-v3 src/

SDK を各言語になじませる

言語固有の慣用表現

Python:snake_case、コンテキストマネージャー、ジェネレーターを使用します

# Pythonic
with client.batch() as batch:
    for user in client.users.list():
        batch.add(user.send_notification("Hello"))

# Not Pythonic
users = client.getUsers()
batch = client.createBatch()
for i in range(len(users)):
    batch.addOperation(users[i].sendNotification("Hello"))
batch.execute()

JavaScript:Promise、async/await、分割代入を使用します

// Idiomatic JS
const { data, error } = await client.users.get(id);

// Not idiomatic
client.users.get(id, function(err, result) {
    if (err) { /* callback hell */ }
});

Go:エラーの返却、インターフェース、チャネルを使用します

// Idiomatic Go
user, err := client.Users.Get(ctx, userID)
if err != nil {
    return fmt.Errorf("getting user: %w", err)
}

// Not idiomatic
user := client.Users.Get(userID)  // panics on error
エコシステムの慣習に合わせる
  • 開発者が想定するパッケージマネージャーを使用します(npm、pip、gem、go get)
  • その言語で人気のライブラリの命名規則に従います
  • 人気のフレームワーク(Express、Django、Rails)と統合します
  • 人気のテストパターンをサポートします

SDK の品質チェックリスト

リリース前
  • すべての公開 API にドキュメントがあります
  • 言語がサポートする場合、すべての公開 API に型があります
  • エラーメッセージに解決手順が含まれています
  • ドキュメントのコード例が自動的にテストされています
  • すべての変更を反映して変更履歴が更新されています
  • 破壊的変更に関する移行ガイドがあります
  • 削除する機能に非推奨警告があります
優れた開発者体験のために
  • クイックスタートが 5 分以内に成功します
  • IDE のオートコンプリートがすべての操作で機能します
  • エラーを特定の型で捕捉できます
  • 再試行ロジックが一時的な障害に対応します
  • ログを設定でき、役立つ情報が記録されます
  • デバッグモードでリクエスト/レスポンスの詳細が表示されます

ツール

SDK の生成
  • OpenAPI Generator:OpenAPI 仕様から SDK を生成します
  • Swagger Codegen:代替のジェネレーターです
  • Speakeasy:最新の SDK 生成プラットフォームです
  • Fern:型安全な SDK 生成ツールです
テスト
  • VCR/Betamax:HTTP インタラクションを記録して再生します
  • WireMock:HTTP サービスをモックします
  • Pact:コントラクトテストを行います
ドキュメント
  • TypeDoc:TypeScript のドキュメント作成ツール
  • Sphinx:Python のドキュメント作成ツール
  • GoDoc:Go のドキュメント作成ツール
  • YARD:Ruby のドキュメント作成ツール

関連スキル

  • docs-as-marketing:SDK の機能を紹介するドキュメント
  • api-onboarding:SDK を初めて利用するときの体験
  • changelog-updates:SDK の変更を効果的に伝える方法
  • developer-sandbox:インストールせずに SDK を試す環境
  • developer-audience-context:SDK の利用者を理解する方法

コメント