Apidog

オールインワン協働API開発プラットフォーム

API設計

APIドキュメント

APIデバッグ

APIモック

API自動テスト

TypeScript で Spectral を使う方法

Mikael Svenson

Mikael Svenson

Updated on 5月 19, 2025

APIを使用するチームにとって、一貫性、品質、および設計標準への準拠を維持することは最も重要です。OpenAPIやAsyncAPIのようなAPI仕様は設計図を提供しますが、これらの設計図が多数のサービスやチーム全体で正しく遵守されていることを保証するのは、困難な課題となり得ます。ここでAPIリンティングツールが活躍し、Spectralは柔軟で強力なオープンソースの選択肢として際立っています。TypeScriptと組み合わせることで、Spectralは開発者が堅牢でタイプセーフなカスタムルールを作成することを可能にし、APIガバナンスを新たなレベルに引き上げます。

このチュートリアルでは、SpectralをTypeScriptと連携させるプロセスを、初期セットアップから洗練されたカスタム検証ロジックの作成までガイドします。TypeScriptがSpectralルールの開発をどのように強化し、より保守しやすく信頼性の高いAPIリンティングソリューションにつながるかを探求します。

💡
美しいAPIドキュメントを生成する素晴らしいAPIテストツールをお探しですか?

最大限の生産性で開発チームが共同作業できる統合されたオールインワンプラットフォームをお探しですか?

Apidogはあなたの全ての要求を満たし、Postmanをはるかに手頃な価格で置き換えます
button

Spectralを理解する:API仕様の守護者

TypeScriptとの連携に入る前に、まずSpectralとは何か、そしてなぜそれがAPI開発ツールキットにおいて価値のあるツールなのかを確立しましょう。

Spectralは、OpenAPI (v2およびv3)AsyncAPIのようなAPI記述フォーマットに焦点を当てたオープンソースのJSON/YAMLリンターです。その目的は、API設計ガイドラインの強制、一般的なエラーの検出、APIランドスケープ全体の一貫性の確保を支援することです。APIコントラクトのためのESLintやTSLintのようなものだと考えてください。

Spectralを使用する主な利点:

  • 一貫性:チームやプロジェクト全体で統一されたAPI設計を強制します。
  • 品質保証:開発ライフサイクルの早期にエラーや不適切な慣行を検出します。
  • コラボレーションの改善:API標準の共通理解を提供します。
  • 自動化:CI/CDパイプラインにシームレスに統合され、自動検証が可能です。
  • 拡張性:特定の組織のニーズに合わせてカスタムルールを作成できます。
  • フォーマットに依存しないコア:OpenAPI/AsyncAPIに優れていますが、そのコアは任意のJSON/YAML構造をリントできます。

Spectralはルールセットに基づいて動作します。ルールセットはルールの集合であり、各ルールはAPIドキュメントの特定の箇所(JSONPath式を使用)をターゲットにし、検証ロジックを適用します。Spectralには組み込みのルールセット(例:OpenAPI標準のためのspectral:oas)が付属していますが、その真の力はカスタムルールセットを定義できることにあります。

SpectralカスタムルールにTypeScriptを使用する理由

SpectralルールセットはYAMLまたはJavaScript(.jsファイル)で定義できますが、カスタム関数の開発にTypeScriptを使用すると、大きな利点があります。

  • タイプセーフティ:TypeScriptの静的型付けはコンパイル時にエラーをキャッチし、カスタムリンティングロジックにおける実行時エラーを減らします。これは複雑なルールにとって非常に重要です。
  • 開発者エクスペリエンスの向上:IDEでのオートコンプリート、リファクタリング機能、およびより優れたコードナビゲーションにより、カスタム関数の記述と保守が容易になります。
  • 可読性と保守性の向上:明示的な型は、特にチームにとって、カスタム関数の意図と構造をより明確にします。
  • 最新のJavaScript機能:TypeScriptは互換性のあるJavaScriptにコンパイルされるため、最新のES機能を自信を持って利用できます。
  • テスト容易性の向上:型付けにより、カスタムSpectral関数の堅牢な単体テストをより簡単に記述できます。

カスタムSpectral関数をTypeScriptで記述することで、アプリケーションコードと同じ厳格さとツールによる利点をAPIガバナンスコードにもたらすことができます。

SpectralとTypeScript環境のセットアップ

実践に移り、必要なツールをセットアップしましょう。

前提条件:

  • Node.jsとnpm (またはyarn):SpectralはNode.jsアプリケーションです。Node.js(LTSバージョンの推奨)とnpm(またはyarn)がインストールされていることを確認してください。
  • TypeScriptプロジェクト:TypeScriptプロジェクトが必要か、またはセットアップする意思がある必要があります。

インストール手順:

まず、リンティング操作を実行し、ルールをテストするためにSpectral CLIが必要です。通常、グローバルにインストールするか、npxを使用するのが便利です。Bash

npm install -g @stoplight/spectral-cli
# or
yarn global add @stoplight/spectral-cli

TypeScriptプロジェクト内でプログラム的にカスタムルールを開発し、Spectralのコアライブラリを使用するには、必要なSpectralパッケージをインストールします。Bash

npm install @stoplight/spectral-core @stoplight/spectral-functions @stoplight/spectral-rulesets typescript ts-node --save-dev
# or
yarn add @stoplight/spectral-core @stoplight/spectral-functions @stoplight/spectral-rulesets typescript ts-node --dev

これらのパッケージを分解してみましょう。

  • @stoplight/spectral-core:リンティングエンジンを含むSpectralの心臓部です。
  • @stoplight/spectral-functions:ルールが使用できる組み込み関数のコレクションを提供します(例:alphabetical, defined, pattern, truthy, xor)。
  • @stoplight/spectral-rulesetsspectral:oas(OpenAPI用)やspectral:asyncapiのような事前定義されたルールセットを提供します。
  • typescript:TypeScriptコンパイラです。
  • ts-node:コンパイルせずにTypeScriptファイルを直接実行できるため、開発に便利です。

TypeScriptの設定:

まだtsconfig.jsonファイルがない場合は、プロジェクトルートに作成してください。基本的な設定は次のようになります。JSON

{
  "compilerOptions": {
    "target": "es2020", // またはより新しいバージョン
    "module": "commonjs",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "outDir": "./dist", // コンパイルされたJavaScriptの出力ディレクトリ
    "rootDir": "./src", // TypeScriptファイルのソースディレクトリ
    "resolveJsonModule": true // JSONファイルのインポートを許可
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "**/*.spec.ts"]
}

プロジェクト構造に合わせてoutDirrootDirを調整してください。カスタムTypeScript関数はsrcディレクトリに配置すると仮定します。

Spectralのコアコンセプト:ルール、ルールセット、関数

TypeScript関数を記述する前に、Spectralの主要なコンポーネントの理解を固めましょう。

ルール:

ルールは実行される特定のチェックを定義します。ルールの主なプロパティは次のとおりです。

  • description:ルールの人間が読める説明。
  • message:ルール違反が発生した場合に表示されるエラーまたは警告メッセージ。{{error}}{{path}}{{value}}のようなプレースホルダーを含めることができます。
  • severity:ルール違反の影響度を定義します。errorwarninfo、またはhintを指定できます。
  • given:ルールが適用されるドキュメントのどの部分を指定するJSONPath式(またはその配列)。
  • then:ターゲット値に対して実行するアクションを定義します。通常、1つ以上の関数を適用します。
  • function:実行する組み込みまたはカスタム関数の名前。
  • functionOptions:関数に渡すオプション。
  • formats:このルールが適用されるドキュメントフォーマットを指定する配列(例:oas3oas2asyncapi2)。

ルールセット:

ルールセットは、ルールをグループ化するYAMLまたはJavaScriptファイル(例:.spectral.yaml、.spectral.js、またはコンパイルされた.spectral.ts)です。また、次のことも可能です。

  • extends:他のルールセット(例:組み込みのSpectralルールセットや共有組織ルールセット)からルールを継承します。
  • rules:カスタムルール定義を含むオブジェクト。
  • functionsDir:カスタムJavaScript関数ファイルが配置されているディレクトリを指定します。
  • functions:カスタム関数の配列(functionsDirまたはプログラムによるセットアップを使用する場合はあまり一般的ではありません)。

関数:

関数は、実際の検証を実行するコアロジック単位です。Spectralは、次のような多くの組み込み関数を提供します。

  • truthy:値がtruthyであるかチェックします。
  • falsy:値がfalsyであるかチェックします。
  • defined:プロパティが定義されているかチェックします。
  • undefined:プロパティが未定義であるかチェックします。
  • pattern:文字列が正規表現に一致するかチェックします。
  • alphabetical:配列要素またはオブジェクトキーがアルファベット順であるかチェックします。
  • length:文字列または配列の長さをチェックします。
  • schema:JSONスキーマに対して値を検証します。

これらの組み込み関数だけでは不十分な場合に、独自のカスタム関数を記述する必要があり、ここでTypeScriptが威力を発揮します。

TypeScriptで最初のカスタムSpectral関数を作成する

簡単なカスタム関数を作成してみましょう。すべてのAPI操作サマリーがタイトルケースであり、70文字を超えないというルールを強制したいと想像してください。

ステップ1:TypeScriptでカスタム関数を定義する

たとえば、src/customFunctions.tsというファイルを作成します。TypeScript

import type { IFunction, IFunctionResult } from '@stoplight/spectral-core';

interface TitleCaseLengthOptions {
  maxLength: number;
}

// 文字列がタイトルケースであり、最大長以内であるかチェックするカスタム関数
export const titleCaseAndLength: IFunction<string, TitleCaseLengthOptions> = (
  targetVal,
  options,
  context
): IFunctionResult[] | void => {
  const results: IFunctionResult[] = [];

  if (typeof targetVal !== 'string') {
    // 'given' パスが文字列を指している場合は発生しないはずですが、良い習慣です
    return [{ message: `パス '${context.path.join('.')}' の値は文字列である必要があります。` }];
  }

  // タイトルケースのチェック(簡単なチェック:各単語の最初の文字が大文字であること)
  const words = targetVal.split(' ');
  const isTitleCase = words.every(word => word.length === 0 || (word[0] === word[0].toUpperCase() && (word.length === 1 || word.substring(1) === word.substring(1).toLowerCase())));

  if (!isTitleCase) {
    results.push({
      message: `パス '${context.path.join('.')}' のサマリー "${targetVal}" はタイトルケースである必要があります。`,
      path: [...context.path], // 違反している要素へのパス
    });
  }

  // 長さのチェック
  const maxLength = options?.maxLength || 70; // 指定がない場合は70をデフォルトとする
  if (targetVal.length > maxLength) {
    results.push({
      message: `パス '${context.path.join('.')}' のサマリー "${targetVal}" は最大長 ${maxLength} 文字を超えています。現在の長さ:${targetVal.length}。`,
      path: [...context.path],
    });
  }

  return results;
};

説明:

  • 型安全性のために@stoplight/spectral-coreからIFunctionIFunctionResultをインポートしています。IFunction<T = unknown, O = unknown>は2つのジェネリック引数を取ります。TtargetVal(リンティング対象の値)の型、Oは関数に渡されるoptionsの型です。
  • targetValgiven JSONPathが指すAPIドキュメントからの実際の値。ここではstringとして型付けしています。
  • options:ルール定義から渡されるオプションを含むオブジェクト(例:{ "maxLength": 70 })。これらのオプションのためにTitleCaseLengthOptionsインターフェースを作成しました。
  • context:リンティングプロセスに関するコンテキスト情報を提供します。これには以下が含まれます。
  • pathtargetValに至るパスセグメントの配列。
  • document:解析されたドキュメント全体。
  • rule:現在処理されているルール。
  • 関数は、違反がある場合はIFunctionResultオブジェクトの配列を返し、問題がない場合はvoid/undefined/空の配列を返します。各IFunctionResultmessageを持ち、オプションでpathcontext.pathと異なる場合)を持つことができます。
  • 私たちのロジックは、簡単なタイトルケース形式と最大長をチェックします。

ステップ2:TypeScript関数をコンパイルする

この関数をfunctionsDirを指す.spectral.yamlまたは.spectral.jsルールセットで使用する予定がある場合は、TypeScriptをJavaScriptにコンパイルする必要があります。

package.jsonにビルドスクリプトを追加します。JSON

{
  "scripts": {
    "build": "tsc"
  }
}

npm run buildまたはyarn buildを実行します。これにより、src/customFunctions.tsdist/customFunctions.jsにコンパイルされます(tsconfig.jsonに基づきます)。

ステップ3:ルールセットファイルを作成する

たとえば、.spectral.jsというルールセットを作成しましょう(完全にTypeScript主導のセットアップを好む場合は.spectral.ts、次のセクションを参照)。

コンパイルされた関数を直接参照するJavaScriptルールセットファイルを使用する場合:JavaScript

// .spectral.js
const { titleCaseAndLength } = require('./dist/customFunctions'); // コンパイルされたJS関数へのパス

module.exports = {
  extends: [['@stoplight/spectral-rulesets/dist/rulesets/oas', 'recommended']],
  rules: {
    'operation-summary-title-case-length': {
      description: '操作サマリーはタイトルケースであり、70文字を超えてはなりません。',
      message: '{{error}}', // メッセージはカスタム関数から来ます
      given: '$.paths[*][*].summary', // すべての操作サマリーをターゲットにします
      severity: 'warn',
      formats: ["oas3"], // OpenAPI v3ドキュメントにのみ適用
      then: {
        function: titleCaseAndLength, // インポートされた関数を直接参照
        functionOptions: {
          maxLength: 70,
        },
      },
    },
    // ここにさらにルールを追加できます
  },
};

または、.spectral.yamlfunctionsDirを使用する場合:

まず、distディレクトリに、関数をエクスポートするindex.jsが含まれているか、またはcustomFunctions.jsが直接エクスポートしていることを確認します。たとえば、dist/customFunctions.jsexports.titleCaseAndLength = ...;がある場合、次のようにできます。YAML

# .spectral.yaml
extends:
  - ["@stoplight/spectral-rulesets/dist/rulesets/oas", "recommended"]
functionsDir: "./dist" # コンパイルされたカスタムJS関数を含むディレクトリ
rules:
  operation-summary-title-case-length:
    description: "操作サマリーはタイトルケースであり、70文字を超えてはなりません。"
    message: "{{error}}"
    given: "$.paths[*][*].summary"
    severity: "warn"
    formats: ["oas3"]
    then:
      function: customFunctions#titleCaseAndLength # customFunctions.jsから関数がエクスポートされていると仮定
      functionOptions:
        maxLength: 70

ここで、customFunctions#titleCaseAndLengthは、SpectralにfunctionsDir内のcustomFunctions.js(またはcustomFunctions/index.js)を探し、エクスポートされたtitleCaseAndLength関数を使用するように指示します。

ステップ4:サンプルOpenAPIドキュメントを作成する

ルールをテストするための簡単なopenapi.yamlファイルを作成しましょう。YAML

# openapi.yaml
openapi: 3.0.0
info:
  title: Sample API
  version: 1.0.0
paths:
  /items:
    get:
      summary: retrieves all items from the store # 不正:タイトルケースではない
      responses:
        '200':
          description: アイテムのリスト。
    post:
      summary: Adds A New Item To The Ever Expanding Collection Of Items In The Store # 不正:長すぎる
      responses:
        '201':
          description: アイテムが作成されました。
  /users:
    get:
      summary: Get User Details # 正しい
      responses:
        '200':
          description: ユーザー詳細。

ステップ5:Spectralを実行する

次に、OpenAPIドキュメントに対してSpectral CLIを実行します。Bash

spectral lint openapi.yaml --ruleset .spectral.js
# またはYAMLルールセットを使用する場合(.spectral.yamlという名前の場合は自動検出されることが多い)
spectral lint openapi.yaml

期待される出力:

次のような警告が表示されるはずです。

openapi.yaml
 2:10  warning  operation-summary-title-case-length  パス 'paths./items.get.summary' のサマリー "retrieves all items from the store" はタイトルケースである必要があります。   paths./items.get.summary
 6:10  warning  operation-summary-title-case-length  パス 'paths./items.post.summary' のサマリー "Adds A New Item To The Ever Expanding Collection Of Items In The Store" は最大長 70 文字を超えています。現在の長さ:78。  paths./items.post.summary

✖ 2 problems (0 errors, 2 warnings, 0 infos, 0 hints)

この出力は、コンパイルされたJavaScriptであるカスタムTypeScript関数が、違反を正しく識別していることを確認しています。

TypeScriptルールセットによるSpectralのプログラム的使用

より複雑なシナリオやアプリケーションへのより密接な統合のために、Spectralをプログラム的に使用し、ルールセット全体をTypeScriptで定義したい場合があります。これにより、必要に応じて個別の.spectral.yamlまたは.spectral.jsファイルが不要になり、動的なルールセット構築が可能になります。

たとえば、src/linter.tsというリンター用のTypeScriptファイルを作成します。TypeScript

import { Spectral, Document } from '@stoplight/spectral-core';
import { oas } from '@stoplight/spectral-rulesets';
import { truthy } from '@stoplight/spectral-functions'; // 組み込み関数の例
import { titleCaseAndLength } from './customFunctions'; // あなたのカスタムTS関数
import type { ISpectralDiagnostic } from '@stoplight/spectral-core';
import * as fs from 'fs/promises';
import * as path from 'path';

// Spectralインスタンスを定義
const spectral = new Spectral();

// 組み込みルールセットと関数をロード
spectral.setRuleset({
  extends: [[oas, 'recommended']], // 推奨されるOpenAPIルールを継承
  rules: {
    'operation-summary-title-case-length': {
      description: '操作サマリーはタイトルケースであり、70文字を超えてはなりません。',
      message: '{{error}}',
      given: '$.paths[*][*].summary',
      severity: 'warn',
      formats: ["oas3"],
      then: {
        function: titleCaseAndLength, // TypeScript関数を直接使用
        functionOptions: {
          maxLength: 70,
        },
      },
    },
    'info-contact-defined': { // 組み込み関数を使用した例
        description: 'Infoオブジェクトはcontactオブジェクトを持つべきです。',
        message: 'API連絡先情報がありません。',
        given: '$.info',
        severity: 'warn',
        formats: ["oas3"],
        then: {
          field: 'contact',
          function: truthy, // 組み込み関数を使用
        },
      },
  },
});

// ドキュメントをリントする関数
export async function lintDocument(filePath: string): Promise<ISpectralDiagnostic[]> {
  try {
    const absolutePath = path.resolve(filePath);
    const fileContent = await fs.readFile(absolutePath, 'utf-8');
    
    // Spectral Documentオブジェクトを作成
    // 2番目の引数(URI)は、$refがあれば相対パスを解決するために重要です
    const document = new Document(fileContent, undefined, absolutePath); 
    
    const results = await spectral.run(document);
    return results;
  } catch (error) {
    console.error('ドキュメントのリントエラー:', error);
    return [];
  }
}

// 使用例(例:スクリプトまたは別のモジュールで)
async function main() {
  const diagnostics = await lintDocument('openapi.yaml'); // API仕様へのパス
  if (diagnostics.length > 0) {
    console.log('APIリンティングの問題が見つかりました:');
    diagnostics.forEach(issue => {
      console.log(
        `- [${issue.severity === 0 ? 'Error' : issue.severity === 1 ? 'Warning' : issue.severity === 2 ? 'Info' : 'Hint'}] ${issue.code} (${issue.message}) at ${issue.path.join('.')}`
      );
    });
  } else {
    console.log('APIリンティングの問題は見つかりませんでした。素晴らしい!');
  }
}

// このファイルをts-nodeで直接実行したい場合
if (require.main === module) {
  main().catch(console.error);
}

これを実行するには:Bash

npx ts-node src/linter.ts

このアプローチは最大の柔軟性を提供します。

  • ルールセット定義のコンパイルステップ不要:ルールセット自体はTypeScriptで定義されます。カスタム関数は引き続きインポートする必要があります(ts-nodeを使用する場合はTSとして、純粋なNodeを実行する場合はコンパイルされたJSとして)。
  • 動的ルール:実行時の条件に基づいてルールセットをプログラム的に構築または変更できます。
  • 直接的な型使用:インポートしたTypeScript関数をルールセット定義内で直接使用し、型安全性とIDE統合を強化します。

高度なカスタム関数テクニック

カスタム関数の作成に関するより高度な側面を探求しましょう。

非同期カスタム関数:

カスタム関数が非同期操作(例:外部リソースをフェッチして検証する、ただしパフォーマンスに注意して使用)を実行する必要がある場合、それをasync関数として定義できます。TypeScript

import type { IFunction, IFunctionResult } from '@stoplight/spectral-core';

export const checkExternalResource: IFunction<string, { url: string }> = 
  async (targetVal, options, context): Promise<IFunctionResult[] | void> => {
  try {
    const response = await fetch(`${options.url}/${targetVal}`);
    if (!response.ok) {
      return [{ message: `リソース '${targetVal}' は ${options.url} で見つかりませんでした。ステータス:${response.status}` }];
    }
  } catch (error: any) {
    return [{ message: `リソース '${targetVal}' のフェッチエラー: ${error.message}` }];
  }
};

Spectralは非同期関数を正しくawaitします。

ドキュメント全体と解決済み値へのアクセス:

context.documentオブジェクトを使用すると、解析されたドキュメント全体にアクセスできます。さらに強力なのは、context.document.resolvedです。これはドキュメントの完全に逆参照されたバージョンを提供し、$refポインターを扱う際に不可欠です。TypeScript

import type { IFunction, IFunctionResult } from '@stoplight/spectral-core';
import {isPlainObject} from '@stoplight/json';

// 例:参照されているスキーマが特定のプロパティを持っていることを確認する
export const referencedSchemaHasProperty: IFunction<{$ref: string}, { propertyName: string }> = (
  targetVal, // これは { $ref: '#/components/schemas/MySchema' } のようなオブジェクトになります
  options,
  context
): IFunctionResult[] | void => {
  if (!targetVal.$ref) return;

  // `context.document.resolveAnchor` メソッドは、$refの解決済み値を見つけることができます
  const resolvedValue = context.document.resolveAnchor(targetVal.$ref);

  if (!resolvedValue || !isPlainObject(resolvedValue.value)) {
    return [{ message: `$ref を解決できませんでした: ${targetVal.$ref}` }];
  }
  
  const schemaProperties = resolvedValue.value.properties as Record<string, unknown> | undefined;

  if (!schemaProperties || schemaProperties[options.propertyName] === undefined) {
    return [{
      message: `パス '${context.path.join('.')}' で "${targetVal.$ref}" によって参照されるスキーマは、プロパティ "${options.propertyName}" を持っている必要があります。`,
      path: [...context.path, '$ref'] // $ref自体を指す
    }];
  }
};

この関数は、$refを含むオブジェクトをターゲットにするgivenパス(例:$.paths[*].*.responses.*.content.*.schema)とともに使用されます。

フォーマットの扱い:

カスタムルールが適用されるフォーマット(例:oas2、oas3、asyncapi2)を指定していることを確認してください。これにより、互換性のないドキュメントタイプでルールが実行されるのを防ぎます。関数内では、context.document.formatsを介して検出されたフォーマットにアクセスできます。

ルールセットの整理と拡張

カスタムルールのコレクションが増えるにつれて、整理が鍵となります。

  • モジュラールールセット:大きなルールセットをより小さく、焦点の絞られたファイルに分割します。extendsプロパティを使用してそれらを組み合わせることができます。JavaScript
// .spectral.js (メインルールセット)
module.exports = {
  extends: ['./rulesets/common-rules.js', './rulesets/security-rules.js'],
  // ... その他のルールまたはオーバーライド
};
  • 共有ルールセット:ルールセットをnpmパッケージとして公開し、異なるプロジェクトやチーム間で共有できます。extendsプロパティはこれらのパッケージを参照できます。
  • シンプルさのためのfunctionsDir多数のカスタムJS関数(TSからコンパイルされたもの)がある場合、.spectral.yamlルールセットのfunctionsDirは、それらすべてをリストアップしたり、完全にプログラム的なセットアップを使用したりするよりもシンプルになる場合があります。コンパイルされたJSファイルが関数を正しくエクスポートしていることを確認するだけです。

Spectralをワークフローに統合する

APIリンティングの真の力は、それが自動化されたときに実現されます。

  • CI/CDパイプライン:spectral lintコマンドをGitHub Actions、GitLab CI、Jenkins、またはその他のCI/CDパイプラインに統合します。重大なエラーが検出された場合はビルドを失敗させます。YAML
# GitHub Actionsステップの例
- name: API仕様をリント
  run: spectral lint ./path/to/your/api-spec.yaml --ruleset ./.spectral.js --fail-severity=error
  • Gitフック:Huskyのようなツールを使用して、コミット前またはプッシュ前のフックでSpectralを実行し、リポジトリに到達する前に問題を検出します。
  • IDE統合:IDE(例:VS Code)用のSpectral拡張機能を探し、API仕様を記述しながらリアルタイムのフィードバックを得ます。

SpectralとTypeScriptカスタムルールのベストプラクティス

  • 明確な説明とメッセージ:ルールに意味のあるdescriptionmessageプロパティを記述します。メッセージは、ユーザーが問題を修正する方法をガイドするべきです。
  • 適切な重要度レベル:重大な違反にはerror、重要な提案にはwarn、情報提供のチェックにはinfo、軽微な提案にはhintを使用します。
  • 正確なgivenパス:JSONPath式を可能な限り具体的にして、意図したノードのみをターゲットにします。これによりパフォーマンスが向上し、誤検知が減少します。
  • 冪等な関数:カスタム関数は可能な限り純粋であるべきです。同じ入力が与えられた場合、副作用なしに同じ出力を生成する必要があります。
  • カスタムルールのテスト:カスタムTypeScript関数に対して単体テストを記述し、さまざまな入力で期待どおりに動作することを確認します。
  • パフォーマンスの考慮事項:非常に大きなドキュメントの場合、パフォーマンスに敏感なルールで複雑な計算や多数のschema関数呼び出しに注意してください。ルールセットのパフォーマンスをテストします。
  • TypeScript型の最新状態維持:カスタム関数が期待するtargetValoptionsを正しく型付けしていることを確認します。これは保守性にとって非常に重要です。

結論:SpectralとTypeScriptでAPIガバナンスを向上させる

SpectralはAPIリンティングのための堅牢なフレームワークを提供し、カスタムルール開発にTypeScriptを活用することで、APIガバナンス戦略に強化された型安全性、開発者エクスペリエンス、および保守性をもたらします。OpenAPIのベストプラクティス、会社固有の命名規則、またはAPI設計内の複雑なビジネスロジックを強制する場合でも、Spectralの柔軟なルールエンジンとTypeScriptの強力な型付けシステムの組み合わせは、強力なソリューションを提供します。

IDEフィードバックからCI/CDパイプラインまで、Spectralを開発ライフサイクルに統合することで、APIが一貫性があり、高品質であり、定義された標準に準拠していることを保証でき、最終的により信頼性が高く、消費しやすいAPIにつながります。小さく始め、ルールセットを繰り返し改善し、より良いAPIを構築するためのツールをチームに提供しましょう。