Upload2Door

API Design

OpenAPI駆動開発でドキュメントが腐らない。ヘッドレス設計で拡張性確保。

APIファースト設計

仕様書 = Single Source of Truth

OpenAPI仕様書を先に書く → 型・クライアント自動生成 → 実装

ヘッドレスアーキテクチャ

事務所Web

Next.js (自社)

外部ベンダー

フォトブックエディタ

モバイルアプリ

iOS/Android (将来)

EC連携

Shopify App (将来)

すべて同じAPIを利用

外部ベンダーにフォトブック編集UIだけ委託可能

OpenAPIから自動生成

生成物ツール用途
TypeScript型定義openapi-typescriptフロント/バックエンド共通型
APIクライアントopenapi-fetchフロントエンドSDK
バリデーションzod-openapiリクエスト検証
APIドキュメントRedoc / Swagger UI開発者向けドキュメント
モックサーバーPrismフロント先行開発

主要エンドポイント

認証系
POST/api/v1/auth/login
POST/api/v1/auth/logout
GET/api/v1/auth/me
案件管理
GET/api/v1/projects
POST/api/v1/projects
POST/api/v1/projects/:id/submit
ファイルアップロード
POST/api/v1/uploads/presign
POST/api/v1/uploads/:projectId/images
工場向け
GET/api/v1/factory/projects
GET/api/v1/factory/projects/:id/download
PATCH/api/v1/factory/projects/:id/status

パフォーマンス目標

50ms
API応答時間(P50)
Sentry Performance
200ms
API応答時間(P95)
Sentry Performance
500ms
API応答時間(P99)
Sentry Performance
0.1%
エラー率
Cloudflare Analytics

外部ベンダー向けSDK

import { createClient } from '@upload2door/sdk';

const u2d = createClient({
  apiKey: 'vendor_xxx',
  baseUrl: 'https://api.u2d.com',
});

// フォトブックレイアウト保存
const layout = await u2d.photobook.saveLayout({
  projectId: 'prj_xxx',
  pages: [
    { pageNumber: 1, images: ['img_1', 'img_2'], template: 'two-photo' },
    { pageNumber: 2, images: ['img_3'], template: 'full-bleed' },
  ],
});

// 入稿確定
await u2d.projects.submit({ projectId: 'prj_xxx' });