Skip to content

画面を1枚定義する ​

どの画面にも要る4つのキーと、レコードを1件に絞る key。

どの画面も、まず「どの種別か」「どのデータを扱うか」を書く。ここが決まれば、あとはその種別が持てるものを足していくだけになる。

yaml
dsl_version: "1.0"

page:
  type: master          # 画面の種別
  id: dept_master       # 画面の識別子(遷移先の指定に使う)
  title: 部門マスタ      # 画面に出る名前
  repository: deptRepository   # データの出し入れ先の名前
  key: code             # 1件を特定する項目

repository は「名前」であって実装ではない ​

repository に書くのは名前だけ。その名前で実際に何をするか(HTTP を叩く、DB を見る、メモリに持つ)は自分のコードで書いて、アプリ起動時に名前と結びつける。Framework は HTTP も DB も知らない。

key を書く画面と書かない画面 ​

key は「この1件」を決めるための項目。詳細表示・編集・削除は、これが無いとどのレコードを触るのか決まらない。

逆に、1件を触らない画面(dashboard / report)には key を書かない。集計しか出さないので特定する対象が無い。

1つの列で決まらないとき ​

受注明細は受注番号だけでは1件に決まらない。行番号と合わせて初めて1件を指す。明細ビュー・履歴表・年度別の実績表と、業務では普通に出てくる形。項目を並べて書く。

yaml
key: [orderNo, lineNo]

並べた順に意味がある。 その順がそのまま REST の道の順になるので(/api/orderLines/SO-1/2)、並べ替えると別の1件を指してしまう。定義の並びは URL の一部だと思って扱う。

画面から画面へ渡すときは、鍵の項目を1つずつ渡す。行き先は自分の key の名前で受け取るので、名前を合わせておけば届く。1つでも欠けていたら取りに行かない ── 欠けたまま組み立てると別の1件が開くので、そろうまで画面は空のまま待つ。

Repository を書き直す必要は無い。1件を指す項目が1つの画面には、いままでどおり素の値("SO-1")が渡る。複合キーの画面だけ、項目名と値の組が渡る。

どの type を選ぶか ​

迷ったら、扱う対象が「一覧か1件か」「読むだけか書くか」で切る。

やりたいことtype
探して一覧に出して、その場で登録・修正・削除までcrud / master
探して一覧に出すだけ(照会)search
1件を読み取り専用で見せるdetail
1件を入力・編集する(一覧なし)form
長い入力を数ステップに分けるwizard
数字とグラフを並べるdashboard
印刷・PDF 向けに出すreport

判断に迷う場合の対照表は ページ種別の選び方 にある。

書けるキー ​

キー書く場所型必須既定値有効なページ種別説明
typeactionstring (create / edit / delete / navigate / plugin / export / print ほか)必須—crud dashboard detail form master report search wizardAction type (open string). Built-ins: create, edit, delete, navigate, plugin, export, print.
typecolumnstring (text / number / badge / boolean / date / dateTime ほか)任意"text"crud dashboard detail form master report search wizardRender type (open string). Built-ins: text, number, badge, boolean, date, dateTime.
typecrudPagestring (crud)必須—crudPage kind.
typedashboardItemstring (metric / table / chart ほか)任意"metric"dashboardCard kind. Open string; built-ins below.
typedashboardPagestring (dashboard)必須—dashboardPage kind.
typedetailPagestring (detail)必須—detailPage kind.
typefieldstring (text / textarea / number / select / multiSelect / checkbox / radio / date / dateTime / time / subTable ほか)任意"text"crud dashboard detail form master report search wizardField type (open string). Built-ins: text, textarea, number, select, multiSelect, checkbox, radio, date, dateTime, time, subTable. A subTable holds child rows — see columns / fields / source.
typefilterstring (text / textarea / number / select / multiSelect / checkbox / radio / date / dateTime / time ほか)任意"text"crud dashboard master report searchInput type (open string). Built-ins: text, textarea, number, select, multiSelect, checkbox, radio, date, dateTime, time.
typeformPagestring (form)必須—formPage kind.
typemasterPagestring (master)必須—masterPage kind.
typereportPagestring (report)必須—reportPage kind.
typesearchPagestring (search)必須—searchPage kind.
typevalidatorstring (required / maxLength / minLength / pattern / min / max / email / postalCode / compare / unique ほか)必須—crud dashboard detail form master report search wizardValidator type (open string). Built-ins: required, maxLength, minLength, pattern, min, max, email, postalCode, compare, unique. compare is the cross-field one (it reads another field of the same record) and unique is the cross-row one (it reads every row of a subTable, so it belongs on the subTable field itself); see the node description for their parameters.
typewizardPagestring (wizard)必須—wizardPage kind.
idactionstring必須—crud dashboard detail form master report search wizard—
idappstring必須—すべて—
idcrudPagestring必須—crudStable page identifier.
iddashboardItemstring必須—dashboardCard identifier.
iddashboardPagestring必須—dashboard—
iddetailPagestring必須—detail—
idformPagestring必須—form—
idmasterPagestring必須—master—
idmenuItemstring任意—すべてRoute key for a leaf (defaults to page).
idreportPagestring必須—report—
idsearchPagestring必須—search—
idwizardPagestring必須—wizard—
idwizardStepstring必須—wizardStep identifier.
titleactionPromptstring任意—crud dashboard detail form master report search wizardDialog heading. Defaults to the action's label.
titleappstring必須—すべて—
titleconfirmstring任意—crud dashboard detail form master report search wizardDialog heading. Omit for the renderer's default. May carry {count}.
titlecrudPagestring必須—crudPage title.
titledashboardItemstring必須—dashboardCard heading.
titledashboardPagestring必須—dashboard—
titledetailPagestring必須—detail—
titleformPagestring必須—form—
titlemasterPagestring必須—master—
titlereportPagestring必須—report—
titlesearchPagestring必須—search—
titlesectionstring任意—crud detail form master—
titlewizardPagestring必須—wizard—
titlewizardStepstring必須—wizardStep heading.
repositorycrudPagestring必須—crudKey resolving the user-provided Repository implementation.
repositorydashboardItemstring任意—dashboardRepository key. Falls back to the page's.
repositorydashboardPagestring任意—dashboardDefault repository key for cards that omit one.
repositorydetailPagestring必須—detail—
repositoryformPagestring必須—form—
repositorymasterPagestring必須—master—
repositoryoptionsSourcestring必須—crud dashboard detail form master report search wizardRepository key holding the choices.
repositoryreportPagestring必須—report—
repositorysearchPagestring必須—search—
repositorysubTableSourcestring必須—crud dashboard detail form master report search wizardRepository key for the child rows.
repositorywizardPagestring必須—wizard—
keycrudPageobject → crudPage.key / crudPage.key任意—crudWhich field identifies one record. A list names a composite key ([orderNo, lineNo]): the parts are read in the order written, and that order is part of the REST path (<collection>/<orderNo>/<lineNo>), so reordering them addresses a different record. Default id.
keydetailPageobject → detailPage.key / detailPage.key任意—detailWhich field identifies one record. A list names a composite key ([orderNo, lineNo]): the parts are read in the order written, and that order is part of the REST path (<collection>/<orderNo>/<lineNo>), so reordering them addresses a different record. Default id.
keyformPageobject → formPage.key / formPage.key任意—formWhich field identifies one record. A list names a composite key ([orderNo, lineNo]): the parts are read in the order written, and that order is part of the REST path (<collection>/<orderNo>/<lineNo>), so reordering them addresses a different record. Default id.
keymasterPageobject → masterPage.key / masterPage.key任意—masterWhich field identifies one record. A list names a composite key ([orderNo, lineNo]): the parts are read in the order written, and that order is part of the REST path (<collection>/<orderNo>/<lineNo>), so reordering them addresses a different record. Default id.
keysearchPageobject → searchPage.key / searchPage.key任意—searchWhich field identifies one record. A list names a composite key ([orderNo, lineNo]): the parts are read in the order written, and that order is part of the REST path (<collection>/<orderNo>/<lineNo>), so reordering them addresses a different record. Default id.
keysubTableSourceobject → subTableSource.key / subTableSource.key任意—crud dashboard detail form master report search wizardWhich field identifies one child row. A list names a composite key; the order is part of the REST path, as on a page.
keywizardPageobject → wizardPage.key / wizardPage.key任意—wizardWhich field identifies one record. A list names a composite key ([orderNo, lineNo]): the parts are read in the order written, and that order is part of the REST path (<collection>/<orderNo>/<lineNo>), so reordering them addresses a different record. Default id.

この表は spec/reference.json から生成している(JSON Schema が正)。手元では npx -p @hatake-fw/api hatake reference <キー名> で同じものが引ける。

近い例 ​

例は丸ごと写して直すのが一番速い。以下は CI で検証済み(そのまま動く形)。

ファイル種別画面どういうときに使うか
customer_detail.yamldetail顧客詳細1件の内容を読み取り専用で表示したい(一覧から開く先)
order_lines.yamlapp受注明細受注番号だけでは1件に決まらない表を出したい(明細・履歴・年度別の実績)

よくある間違い ​

dashboard / report に key を書く ​

なぜ駄目か key は「1件のレコードの主キー項目名」。ダッシュボードと帳票は単一レコードを指さないので持たない。

こう直す 消す。行から1件を開きたいなら navigate アクションで detail ページへ渡す(params: { id: "$row.id" })。

yaml
page:
  type: report
  id: sales_report
  title: 売上明細表
  repository: orderRepository
  key: id
  table:
    columns:
      - { field: amount, label: 金額, type: number }
yaml
page:
  type: report
  id: sales_report
  title: 売上明細表
  repository: orderRepository
  table:
    columns:
      - { field: amount, label: 金額, type: number }

spec/pitfalls.json から生成。各項目は CI で検証済み(間違いは本当に落ち、正しい方は本当に通る)。手元では npx -p @hatake-fw/api hatake pitfalls <キー名>。

実物を見る ​

デモアプリの「顧客マスタ」がこれを使っている。 デモを開く