Modeler の REST API 仕様書
mirel Studio Modeler の REST API 仕様を定義する。すべてのエンドポイントは /mapi/studio/ をベースパスとする。
| 原則 | API 設計への反映 |
|---|---|
| Model-Driven Everything | Model 定義を取得すれば UI/バリデーション/データ構造が決定する |
| Consistency First | 型変更は Draft → Publish フローで整合性を検証 |
| Release as a Unit | Release Center 連携 API で一括デプロイ可能 |
interface ApiRequest<T = Record<string, any>> {
content: T;
}interface ApiResponse<T = Record<string, any>> {
data: T;
messages: string[];
errors: string[];
errorCode?: string;
}| コード | 説明 |
|---|---|
VALIDATION_ERROR |
入力検証エラー |
NOT_FOUND |
リソースが見つからない |
DUPLICATE_KEY |
キー重複 |
PERMISSION_DENIED |
権限不足 |
DRAFT_CONFLICT |
Draft 競合 |
PUBLISH_FAILED |
公開失敗 |
POST /mapi/studio/listModels
// Request
interface ListModelsRequest {
includeHidden?: boolean;
status?: 'all' | 'draft' | 'published';
}
// Response
interface ListModelsResponse {
entities: ModelSummary[];
views: ModelSummary[];
codes: CodeGroupSummary[];
draftCount: number;
}
### 3.2 モデル詳細取得
**`GET /api/studio/models/{id}`**
```typescript
// Response
interface ModelDetailsDto {
header: StuModelHeader;
fields: StuModel[];
flows: StuFlow[];
}GET /api/studio/models?q={query}&status={status}
// Response
interface List<StuModelHeader> {}POST /api/studio/models
PUT /api/studio/models/{id}/draft
POST /api/studio/models/{id}/publish
DELETE /api/studio/models/{id}/draft
POST /api/studio/models/{id}/validate
POST /mapi/studio/searchModels
// Request
interface SearchModelsRequest {
query: string;
types?: ("entity" | "view" | "code")[];
limit?: number;
}
// Response
interface SearchModelsResponse {
results: SearchResult[];
total: number;
}POST /mapi/studio/listSchema
// Request
interface ListSchemaRequest {
modelId: string;
}
// Response
interface ListSchemaResponse {
schemas: FieldDefinition[];
}POST /mapi/studio/saveDraft
// Request
interface SaveDraftRequest {
modelId: string;
header?: Partial<ModelHeader>;
fields?: FieldDefinition[];
relations?: RelationDefinition[];
}
// Response
interface SaveDraftResponse {
modelId: string;
draftVersion: number;
changeCount: number;
}POST /mapi/studio/publish
// Request
interface PublishRequest {
modelId: string;
force?: boolean;
}
// Response
interface PublishResponse {
modelId: string;
publishedVersion: number;
publishedAt: string;
}POST /mapi/studio/discardDraft
// Request
interface DiscardDraftRequest {
modelId: string;
}
// Response
interface DiscardDraftResponse {
modelId: string;
discardedChangeCount: number;
}POST /mapi/studio/createModel
// Request
interface CreateModelRequest {
modelId: string;
modelName: string;
modelType: "entity" | "view";
modelCategory: "transaction" | "master";
description?: string;
copyFrom?: string;
}
// Response
interface CreateModelResponse {
modelId: string;
created: boolean;
}POST /mapi/studio/deleteModel
// Request
interface DeleteModelRequest {
modelId: string;
force?: boolean;
}
// Response
interface DeleteModelResponse {
modelId: string;
deleted: boolean;
warnings?: string[];
}POST /mapi/studio/listCodeGroups
// Request
interface ListCodeGroupsRequest {
includeDeleted?: boolean;
}
// Response
interface ListCodeGroupsResponse {
groups: string[];
groupDetails?: CodeGroupSummary[];
}POST /mapi/studio/listCode
// Request
interface ListCodeRequest {
id: string; // groupId
includeDeleted?: boolean;
}
// Response
interface ListCodeResponse {
valueTexts: CodeValue[];
groupName?: string;
status?: "draft" | "published";
}POST /mapi/studio/saveCode
// Request
interface SaveCodeRequest {
groupId: string;
groupName?: string;
details: CodeValue[];
publishImmediately?: boolean;
}
// Response
interface SaveCodeResponse {
groupId: string;
savedCount: number;
}POST /mapi/studio/list
// Request
interface ListRecordsRequest {
modelId: string;
page?: number;
size?: number;
query?: string;
sort?: string;
order?: "asc" | "desc";
filters?: Record<string, any>;
}
// Response
interface ListRecordsResponse {
records: Record<string, any>[];
total: number;
page: number;
size: number;
totalPages: number;
}POST /mapi/studio/save
// Request
interface SaveRecordRequest {
modelId: string;
recordId?: string;
record: Record<string, any>;
}
// Response
interface SaveRecordResponse {
recordId: string;
isNew: boolean;
}POST /mapi/studio/validate
// Request
interface ValidateRequest {
modelId: string;
fields?: FieldDefinition[];
}
// Response
interface ValidateResponse {
valid: boolean;
errors: ValidationError[];
warnings: ValidationWarning[];
}POST /mapi/studio/publishAll
// Request
interface PublishAllRequest {
modelIds?: string[];
description?: string;
}
// Response
interface PublishAllResponse {
releaseId: string;
releaseVersion: number;
publishedModels: { modelId: string; version: number }[];
failedModels: { modelId: string; error: string }[];
}POST /mapi/studio/validateRelease
// Request
interface ValidateReleaseRequest {
modelIds?: string[];
}
// Response
interface ValidateReleaseResponse {
valid: boolean;
errors: ValidationIssue[];
warnings: ValidationIssue[];
breakingChanges: BreakingChange[];
}Powered by Copilot 🤖