2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【実践編】TypeSpecで始めるAPI設計

2
Last updated at Posted at 2025-12-24

1. はじめに

以前の記事「初学者用:TypeSpecとOpenAPIの基本的概要」ではそれぞれの基本的な概念について触れましたが、今回は「実践的にどう使用するのか」について書いていこうと思います。OpenAPI(Swagger)のYAML管理に悩まされている方々へ、TypeSpecによるクリーンでモダンな設計手法について提案します。

2.TypeSpecでAPI設計を始める前に考えること

実践前に、改めて整理しておくべき「マインドセット」が3つあります。

TypeSpecとOpenAPIの役割分担
改めて、両者の関係性を再定義します。

TypeSpec: 「人間が設計するための言語

OpenAPI: 「ツールやプログラムのための成果物

「まず設計を整える」意識
YAMLを書いていると「どう記述するか(構文)」を考えがちですが、TypeSpecなら「どうあるべきか(設計)」に集中できます。
個人的には、コードを書く前に必要なインターフェースを整理すると設計しやすかったです。

3. 実務でのディレクトリ構成

TypeSpecはTypeScriptのようにファイルを分割・インポートできます。1ファイルに全てを詰め込まず、役割ごとに整理することができます。

3.1 基本、応用的な構成例

基本的な構成
projectFolder
├── models.tsp    #データモデル(User,Product)
├── api.tsp       #APIエンドポイントの定義
└── commn.tsp     #共通定義(エラー型、ページング)
応用的な構成例
projectFolder
├── models/
    └── model.tsp  #データモデル
├── routes/
    └── api.tsp    #APIエンドポイントの定義
└── namespace.tsp  #共通のエンドポイント、namespace、URLなどの宣言 

3.2 ファイルを分割する3つのメリット

  • 影響範囲の最小化
    修正が特定のファイル(例:User.tsp)に限定されるため、どこで変更されたかなど修正点がわかります。

  • 「型の再利用」と「関心の分離」
    データ構造(データモデルなど)とAPI定義を分けることで、共通のデータモデルを複数のAPIで使い回すことができるようになります。

  • エラー発見
    ファイルをまたぐようなインポートも、TypeSpecのコンパイラがチェックしているので、コンパイル実行前にドキュメントの不整合を防ぐことができる。

4.実際のTypeSpecコード例

では実際にTypeSpecで定義を書き、期待される出力結果(OpenAPI)を見てみます。

model定義例
namespace ProjectX {

 @summary("ユーザモデル定義")
  model User {
   @summary("ユーザID")
   userId:integer;
   
   @summary("ユーザ名")
   userName:string;
   
   @summary("ロール情報")
   role:roleData[];  #ロール権限モデル定義を参照
 }

 @summary("ロール権限モデル定義")
 model roleData {
   @summary("ロール権限")
   roletype: 1|2;

   @summary("役職名")
   label:string;
 }
 
}
api定義例
namespace ProjectX.Application {

  @get
  @summary("ユーザ一覧取得")
  @route("projectx/api/user/")
  op getUserData(
     @path
     @summary("企業ID")
     comapanyId:integer;
  ):User;

}
期待される出力結果:OpenAPI
openapi: 3.0.0
info:
  title: ProjectX API
  version: 0.0.0
tags: []
paths:
  /projectx/api/user/{comapanyId}:
    get:
      summary: ユーザ一覧取得
      operationId: getUserData
      parameters:
        - name: comapanyId
          in: path
          required: true
          description: 企業ID
          schema:
            type: integer
      responses:
        '200':
          description: The request has succeeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
components:
  schemas:
    User:
      type: object
      summary: ユーザモデル定義
      properties:
        userId:
          type: integer
          description: ユーザID
        userName:
          type: string
          description: ユーザ名
        role:
          type: array
          items:
            $ref: '#/components/schemas/roleData'
          description: ロール情報
      required:
        - userId
        - userName
        - role
    roleData:
      type: object
      summary: ロール権限モデル定義
      properties:
        roletype:
          type: integer
          description: ロール権限
          enum:
            - 1
            - 2
        label:
          type: string
          description: 役職名
      required:
        - roletype
        - label

@summary@routeなどの「デコレータ」については別の記事でまとめようと考えています。

5. まとめ

TypeSpecを実務に取り入れることで、YAML管理から解放され、API設計に注力できます。

今回のポイントは以下の通りです。
・TypeSpec = 設計、OpenAPI = 「成果物」と割り切る。
・ディレクトリ分割により、保守性と再利用性を高める。
・コンパイラの力を借りて、不整合のないドキュメントを維持する。

私は最初からAPI設計をTypeSpecで行い、コンパイルしてOpenAPIを生成しました。
しかし、従来のAPI設計手法、YAMLの管理を知れば知るほどTypeSpecでのモダンAPI設計がメジャーになっていってほしいと思います。

2
1
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
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?