Service Catalog を使用すると、サービス フォームをすばやく簡単に作成できます。 以下は、最適なサービス フォームを設計するため一般的なガイドラインと原則です。
-
JavaScript コードはディクショナリに固有である必要があります。 コードの各機能がスタンドアロンであり、他の機能またはディクショナリに依存していないことを確認します。 これにより、新しいディクショナリが追加されたり既存のディクショナリが削除されてもコードの機能が保証されます。 たとえば、特定のサービスで使用されている 2 つのディクショナリに、onLoad イベントで実行する必要のあるコードが存在すると仮定します。 一体となった大きな関数を 1 つ記述するよりも、次のように、ディクショナリに固有の関数を 2 つ記述して、それらをライブラリに配置し、スクリプトとして定義され、onLoad イベントとしてフォームにアタッチされたラッパー関数からそれらを呼び出します。
Common_Service_onLoad () { IT_Dictionary1_onLoad(); IT_Dictionary2_onLoad();}
-
サービスに依存しないコードを作成します。 1 つのサービスでコードをテストするだけで、そのコードを使用するすべてのサービスが検証されます。 前の例のコードは、サービスに依存しません。 Common_Service_onLoad() 関数は、一方または両方のディクショナリが欠落しているサービスで実行すると失敗します。 しかし、これは簡単に修正できます。
Common_Service_onLoad () { if (serviceForm.ITDictionary1 !- undefined) { IT_Dictionary1_onLoad(); } if (serviceForm.ITDictionary2 !- undefined) { IT_Dictionary2_onLoad();}
上記のコードで、ディクショナリに固有のコードを適用する前に、サービスにディクショナリが存在するかテストしているように、フィールドに固有のコードを適用する前に、特定のフィールドが存在するかテストする必要がある場合があります。 ベスト プラクティスは、ディクショナリを 1 つのアクティブ フォーム コンポーネントだけで使用することです。しかし、サービスに固有のルールは、ディクショナリの外観に影響を与える可能性があります。 たとえば、サービスを要求する個人に対する上司情報の表示は、上司の承認が必要なサービスに対してのみ必要です。 したがって、上司に関連するフィールドを操作するコードを、次のようなコード ブロックに含める必要があります。
FirstApprover_onLoad () { if (serviceForm.FirstApprover.SupervisorName !- undefined) {// code goes here; }}
フィールドはフォーム内で使用できますが、前に実行されたルールまたは ISF コードによっては、非表示になる場合があります。 このような場合には、次のようなコードがより適切であり、またより堅牢です。
if (serviceForm.FirstApprover.SupervisorName !- undefined) { if (serviceForm.FirstApprover.SupervisorName.isVisible()) {// code goes here; }
-
ブラウザ セッションにより少ないデータを送信します。フォームをロードするときにフォームのパフォーマンスを向上させるには、より少ないデータをブラウザ セッションに送信する必要があります。 以前のリリースの Service Catalog では、操作が必要なディクショナリ フィールドは、ブラウザに送信して操作する必要がありました。 サーバ側のイベントを使用して、より少ないデータがブラウザに送信されるように、また、サーバ側の実行の制御下でセンシティブ データを保持し、その結果傍受されないように、ディクショナリ内のデータを操作できます。 サーバ側データ取得ルールを参照してください。 より少ないデータを送信ために、次を行うことができます。
-
少なくともオーダー時以外にブラウザ セッションにロードする必要がないグループ フィールドは、1 つ以上の「非ロード」ディクショナリにグループ化する必要があります。 「非ロード」ディクショナリの一般的な例としては、パラメータをオーケストレーション エージェントに提供するディクショナリがあります。 オーケストレータは通常、ユーザがフォームで確認できるデータより多くのデータを必要とします。 このデータは通常、ユーザが誰か、ユーザのロールは何か、ユーザの OU メンバーシップは何かなどを判断する条件付きルールまたはデータ取得ルールを通して取得されます。これらはすべて、フォームがブラウザにロードされる前(ロード前イベント中)、またはユーザが [送信(Submit)] ボタンをクリックした際(送信後イベント中)のいずれかが、抽出する最適なタイミングとなります。
送信後イベントが発生するまで設定されている値を確認できないため、「非ロード」のディクショナリで動作するルールの効果を確認するには、通常よりも多くのテストを必要とします。 したがって、「非ロード」のディクショナリの使用には通常、フォームで定義されたすべてのディクショナリを確認できるサービス ディクショナリの管理権限を持つユーザとして、後続の時点(たとえば、サービス グループの承認またはサービスの提供)でフォームを確認することが含まれます。
-
ロード中イベントではなくロード前イベントを使用します。 一般に、条件付きルールとデータ取得ルールは、ブラウザに存在するオブジェクトに対してアクションを実行します。 したがって、ロード前イベントに関連付けられている条件付きルール「フィールドの非表示」の場合、実際には非表示にされるフィールドはありません。これは、ロード前イベント中は非表示にするフィールドがまだ存在しないためです。 前に「非ロード」のディクショナリで説明したように、この一般的なルールには、注目すべき例外があります。
値の設定条件付きルールのアクション、またはデータ取得ルールのいずれかを通して、ブラウザにロードされていないフィールドの値を操作できます。
条件付きルールとデータ取得ルールの機能は非常に柔軟であり、複数のターゲットに複数のルールのアクションを組み合わせること、また任意の 1 つのルールを複数のイベントに関連付けることができます。 ターゲットにアクセスできないアクション(たとえば、実際にはサービス フォームに存在しないフィールドでの値の設定アクション)は、「メッセージを出力せずに失敗」するか、または効力がないと考えられます。 一連のアクション(たとえば、いくつかのフィールドの非表示化、他のフィールドの必須化、アラート メッセージのポップアップ、さらに値の設定の実行)を実行する条件付きルールがある場合、ブラウザで、そのほとんどのアクションの実行を確認できます。 ただし、ターゲット フィールドが現在非表示になっているか、またはブラウザ内に存在しないために、値の設定アクションの実行がブラウザに表示されない可能性があります。 条件付きルールのフレームワークでは、そのようなルールも作成できますが、実行できないアクションは、単に無視されます。
これらの動作については、ルールを構築する際に、条件付きルールとデータ取得ルールのウィザードで詳しく説明されます。 各ステップに組み込まれているヘルプ テキストには、サーバ側イベントで特定のアクションを使用する際に生じる制限が説明されています。
-
サーバ側イベントでは、データベースに直接データを書き込むことができます(具体的には、要求エントリごとにデータベースに格納される WDDX データ)。 特に、送信後イベントは、ブラウザでのアクションによって収集または取得したデータをデータベースに書き込みます。
ロード前イベントと送信後イベントの重要な違いは、ロード前イベントがデータベースに書き込むことができるのは、要求データがすでにデータベースに存在する場合に限られるという点です。 言いかえれば、ユーザがまだ [発注(Order)] ボタンまたは [追加と確認(Add & Review)] ボタンをクリックしていない場合、要求に対するデータがデータベースに存在しないため、ロード前ルールで操作される対象はありません。 ロード前イベントでは表示可能な値を変更できますが、その値をデータベースに保持しません。 送信後イベントは値を保持します。
-
サーバ側のイベントによって、サーバによってこれから保護されるサービス フォームの一部であるデータの操作に対し大きな柔軟性が提供されます。 これは、「非ロード」のディクショナリがデータベースに格納されることで、サーバ側ルールによってアクセス可能になったためです。 ブラウザ側ルールはフォーム上で JavaScript として生成されますが、これらのルールと同等のサーバ側ルールは Java コードとして生成されます。つまり、2 つの異なる表現でルールを生成できるということです。 ISF フレームワーク(インタラクティブ サービス フォーム(ISF)API の概要で説明)を使用すると、フォーム データと外観に対してより複雑な操作を行う JavaScript を記述できます。 この JavaScript は、ブラウザでのみ実行できます。 したがって、作成した ISF 関数は、サーバ側イベントに関連付けることはできません。
-
この [サーバ側でのみ編集可能(Editable on server-side only)] オプションは、入力タイプが読み取り専用または非表示に定義された任意のフィールドの [HTML表現(HTML Representation)] タブで使用可能で、競合することがある要件を満たすために役立ちます。まず、要求側ユーザに役立つデータを表示したり、ビジネス ロジックを適用する「非表示変数」をフォームで使用します。次に、データをユーザによる介入(悪意のあるアクティビティなど)から完全に保護します。
このフラグは、一般に次の 2 つの場合に使用します。
-
- ディクショナリ モジュール内に作成可能な個人ベースのディクショナリである「テンプレート ディクショナリ」
- ディクショナリ モジュール内に構造が自動的に作成されるサービス項目ベースのディクショナリ
この 2 つのディクショナリは、「自動入力」動作を実行する点で類似しています。 個人ベースのディクショナリでは、フォーム ユーザが個人を選択([人を選択します(Select Person)] コントロールを使用)します。選択された個人の詳細は、フォームに自動的に表示されます。 サービス項目ベースのディクショナリでは、フォーム ユーザは、所有する、またはアクセス権を持つ特定のサービス項目を選択できます。そのサービス項目インスタンスの属性値は、自動的に表示されます。
これは、読み取り専用のフィールド(つまり、[HTML表現(HTML Representation)] タブで入力タイプが「読み取り専用」として設定されたフィールド)として自動的に入力される大部分の属性(またはすべての属性)を定義する一般的なサービス設計技法です。 たとえば、ユーザ ベースに同じ名前の複数の人物を格納するための十分なスペースがある場合は、これらの人物の電子メール アドレスなどの属性を使用してフォーム ユーザを区別し、目的の個人を正しく選択できます。 ここでは、フォーム ユーザが、選択したユーザの電子メール アドレスを更新することは想定していません。 一方、フォーム ユーザはこの人物を良く知っており、その人物がディレクトリ統合を通して取得した卓上電話番号ではなく、携帯電話だけを使用していることを知っているかもしれません。 この場合は、[勤務先電話(Work Phone)] フィールドを読み取り専用ではなく、編集可能にして、少なくとも要求を処理するサービス提供担当者が、選択した個人に到達するために最も信頼できる方法を確保します。
[サーバ側でのみ編集可能(Editable on server-side only)] チェック ボックスを使用すると、入力タイプに読み取り専用または非表示としてマークを付けたフィールドがサーバによって完全に制御され、ブラウザ セッションでこれらの値を操作しても、Service Catalog データベースに存在するデータが優先され、操作が破棄されます。 実際、データベース内に存在するデータを上書きする唯一のメカニズムは、サーバ側イベント中に実行するルール(条件付きルールまたはデータ取得ルールのいずれか)であり、この場合はルールが実際にデータベース値を更新します。 (個人ベースのディクショナリの場合、DirPerson 内の個人レコードは更新されませんが、データベースに格納されている、要求エントリに対する WDDX データは更新されます)。
言いかえれば、サービス設計者は、サーバ側イベント中に実行されたルールを通してのみ、[サーバ側でのみ編集可能(Editable on server-side only)] としてマーク付けされているフィールドの値を操作できます。 サービス設計者は、これら「保護された」フィールドを使用するには、[サーバ側でのみ編集可能(Editable on server-side only)] フラグのチェックをオンにするだけでよいと考える可能性があるため、これは考慮すべき重要な要因です。 データベースから返される値を操作する理由がない場合は、チェックをオンにするだけで十分です。 しかし、フォーム ユーザが行った選択に応じてこれらの値を設定するようにビジネス ロジックで要求されている場合、条件付きルール(値の設定アクションの場合)またはデータ取得ルール(クエリからのデータ提供の場合)をサーバ側イベントに必ず関連付ける必要があります。
- 名前付け規則:表記上はまったく問題ありませんが、ディクショナリ、フォーム、およびフィールドには同じ名前を付けないでください。 同じ名前を付けると、非常にわかりにくくなる場合があります。 ディクショナリはプレフィックス表記法を使用して、その使用方法と、場合によっては格納されているディクショナリ グループを示すのが理想的です。 たとえば、「Reason」ディクショナリには、かなり汎用的な響きがあり、多くのフォームで使用されているように思われます。 したがって、「Common」などの名前が付けられたディクショナリ グループに配置して、ディクショナリ名にこのディクショナリ グループを示すコードのプレフィックスを付ける(たとえば、CMN_Reason)と理解しやすくなります。 ディクショナリ グループは、サービス固有のディクショナリが使用されているサービス グループ、または場合によっては、ディクショナリおよびサービスを開発している会社の部門や部署を反映している場合があります。
また、容易に理解できるフォームの表記も必要です。 これは、同じディクショナリまたはディクショナリのグループを使用している複数のフォームを区別する必要がある場合に特に重要です。
- フォーム/ディクショナリ関係:1 つのフォームにはディクショナリが 1 つ必要です。 次のような場合には、複数のディクショナリを同じフォームに含める必要があります。
- これらのディクショナリがすべて同じサービスで必要とされる場合。
- ディクショナリが表示される順序がすべてのサービスで同じ場合。
- このフォームのディクショナリ間で、これ以上表示するディクショナリがない場合。 サービス フォームでは、1 つのフォーム コンポーネント内のすべてのディクショナリが、そのコンポーネントで指定された順序で表示されます。そして、そのサービスに含まれている次のフォーム コンポーネントのディクショナリが、指定された順序で表示されます。以下同様です。
次に、例を示します。
- 施設部門に対して開発されたサービスのグループは、カスタマーの役職や部門に基づき、最大 3 人の承認者によって構成されている承認のチェーンがあると想定します。 この場合、Facilities_Approval フォームは、FirstApprover、SecondApprover、および ThirdApprover の 3 つのディクショナリを含む必要があり、また 3 つの承認うち、実際に収集が必要な承認の数を判断するルールを含む必要があります。
- 施設部門に対して開発された大部分のサービスでは、最大 3 つの標準的な承認を必要としますが、さらに高価なサービスには VP レベルの追加の承認者を必要とするものと想定します。 次の 2 つの対処法があります。
1 つのフォーム(One Form) |
FirstApprover、SecondApprover、および ThirdApprover に加えて、VP Approver ディクショナリが含まれるように Facilities_Approval フォームを修正し、その 1 つのサービスに対してのみ、VPApprover ディクショナリを表示および処理する追加のルールまたはルール群を記述します。 |
複数のフォーム(Multiple Forms) |
VPApprover ディクショナリを含む別のフォーム Facilities_VP_Approval を作成し、FirstApprover ディクショナリ、SecondApprover ディクショナリ、および ThirdApprover ディクショナリの処理に必要な HTML、アクセス コントロール、およびルールを複製します。 |
ほとんどの場合、最初のソリューション(わずかに複雑なフォーム)を優先する必要があります。 複数のフォームで、3 つのディクショナリおよびそれらに関連付けられたルールを設定する作業を重複して行う必要はありません。 これらのディクショナリまたはそれらのルールを変更する必要がある場合、それらを変更する場所は 1 箇所のみです。 2 番目のソリューション(部分的に冗長な 2 つのフォーム)は、ディクショナリを追加することにより、他方のディクショナリの表示または処理方法も変更される場合のみ使用を考慮する必要があります。
- 同じディクショナリに対して異なるレンダリング:フォームが使用されるサービスに基づいて、フォームの動作と外観が大幅に変わる必要があるとしたらどうでしょうか。 さまざまなシナリオを選択できます。 次に記載された条件に基づいて優先されるシナリオを決定できるのは、サービス設計者に限られます。 たとえば、実質的にすべてのサービスに、「Reason」ディクショナリが含まれている必要があります。 しかし、フィールド ラベルは、「Reason」、「Justification」、または「Explanation」の場合があります。 さらに、フィールドに関連付けられたヘルプ テキストは、サービスまたはサービスのグループごとに大幅に異なる必要があります。 この場合、ディクショナリは単純で容易に設定できるため、判断は容易です。ディクショナリのレンダリングごとに別々のフォームを作成し、対応するサービスに適切なフォームを含めます。
しかし、サービスごとにカスタマイズの必要な単一または複数のフィールドが、潜在的に複雑なルールを持つ大きなディクショナリの一部の場合はどのようになるでしょうか。 ここでも、上述と同じ 2 つのオプション(1 つのフォームまたは複数のフォーム)を選択できます。 それでも、次の対応を試してください。
1 つのフォーム(One Form) |
フォームを 1 つ作成し、ISF 関数を使用してその外観をカスタマイズします。 |
複数のフォーム(Multiple Forms) |
ディクショナリのレンダリングごとに異なるフォームを作成します。 |
[1つのフォーム(One-Form)] オプションは、条件付きルールを使用してディクショナリの外観をカスタマイズできないという事実によって複雑になっています。条件付きルールは、フィールドの外観と動作のみを変更し、フィールドのラベルやヘルプ テキストの内容は変更しません。 [複数のフォーム(Multiple-Forms)] オプションには、前記と同様の欠点があります。事前にフォームの作成作業を行う必要があり、またルールを維持するメンテナンス作業を複数の場所で行う必要があります。
次の 2 つの追加のオプションを選択できます。
-
- 要件を変更します。 サービスの要求時に情報を提供する方法に関し、ユーザに提供される情報が減少する可能性があるため、このオプションは推奨されていません。
- 問題があるフィールドを、複数のフォームで使用される個別のディクショナリに移動し、ディクショナリの残りの部分に対してはフォームを 1 つに維持します。 これは、そのフィールドが他のフィールドの間に表示されるのではなく、他のすべてのフィールドの前または後に表示できる場合にのみ可能です。
- ディクショナリ、フォーム、ルールおよびサービス:フォームは通常、ディクショナリのセットおよびルールのセットから構成されます。
- ルールは、同じフォーム内のディクショナリ(およびそれらのフィールド)だけでなく、他のフォーム内のディクショナリにも影響を与える可能性があります。
- 特定のサービスのコンテキストでルールを徹底的にテストし、参照されるすべてのディクショナリがそのサービスに含まれるフォーム内に存在することを確認することが非常に重要です。 ベスト プラクティス レポートには「サービス内のディクショナリ」レポートが含まれます。これを使用すると、このテストの実行、および提案された変更がディクショナリまたはルールに与える潜在的な効果を調べるための影響分析が容易になります。
また、特定のサービスに適用されるルールのみが含まれるように Form 2 を構成する場合にも最適です。 多くのサービスは、Form 1 のみを含むことができますが、追加の要件付きサービスのみ Form 2 を含みます。 これにより、Form 2 のルールに必要な条件が大幅に簡素化(場合によっては不要化)され、適切なサービスに対してのみ実行されることが保証されます。
また、サービス名(変更される可能性のあるテキスト要素)をテストする条件付きルールを記述する必要もなくなります。 影響を受けるサービス内に、影響を受けるディクショナリ持つフォームに続いて、順番にルール専用フォームを含めることのみ必要となります。 ルールは、フォームがサービスに含まれる順序に従って、次にルールがフォーム内に配置される順序に従って実行されます。
- 疎結合されたルールおよびディクショナリと 密結合されたルールおよびディクショナリ:ルールとそのルールが影響を与え、参照するディクショナリが同じ AFC 内にある場合、そのルールとディクショナリは「密結合」されているといいます。 別のフォーム内のディクショナリの外観に影響を与えるルールを使用した上記の例では、ルールとディクショナリは「疎結合」されています。 一般に、両方のフォームが同じサービスに含まれる場合、ルールは、任意のフォーム内のディクショナリに影響を与えることができます。 ただし、疎結合されたルールとディクショナリには、1 つ重要な制限事項があります。つまり、1 つのフォーム内で定義されたルールは、別のフォーム内のディクショナリのフィールドにアタッチされたフィールド レベル イベントによってトリガーすることができません。 したがって、疎結合されたルールは、通常、フォームがロードまたは送信されたときに、フォーム レベル イベントによってトリガーする必要があります。
- ルール、ISF および要求ライフ サイクル:要求が送信されると、ディクショナリのすべての定義、HTML 表現、アクセス制御、およびそのサービスのタスク計画が、要求データとともに保存(圧縮形式)されます。 これにより、処理中の要求のサービス フォームの動作または外観に影響を与えるフォームの定義を後から変更することなく、承認時点と提供時点を通して要求を処理できます。
ディクショナリを変更すると、そのディクショナリを使用するすべてのフォームが自動的に変更を継承します。また、それらのフォームを使用するすべてのサービスも変更を継承します。 保存されているが送信されていない、変更されたサービスに対するすべての要求は、古い要求としてマーク付けされます。 要求をキャンセルするかサービスを削除し、それを読み込み、サービス フォームにデータを入力する必要があります。 送信された要求は、ディクショナリまたはアクティブ フォーム コンポーネントへの変更によって影響されません。
ただし、ルールと ISF 関数(スクリプトまたは外部のライブラリにある)は、サービス フォームが My Services または Service Manager に表示されると、常に動的にロードされます。 したがって、現在のバージョンのルール/コードが、すでにフォーム上に存在しないフィールドを参照しないこと、または逆に、もう使用されていない前バージョンのフォーム上のフィールドは、関連する関数を持つことができることを確認する必要があります。 前に説明したように、この柔軟性は、ISF を介してディクショナリまたはフィールドを操作する前に、ディクショナリまたはフィールドが存在することを常に確認することによって容易に実現できます。 必要に応じて、異なるバージョンのライブラリを新しいバージョンのフォームにアタッチできます。これにより、たとえば、関数の名前を変更することなく、改訂された要件に準拠してその内容を更新できます。
- ディクショナリまたはアクティブ フォーム コンポーネントの変更:ディクショナリ内のフィールドの定義を変更すると、すべてのアクティブ フォーム コンポーネントがその変更を反映します。 同様に、アクティブ フォーム コンポーネント定義の任意の側面を変更すると、その変更はそのフォームを使用するすべてのサービス定義に反映されます。 条件付きルールに関連付けられたディクショナリやディクショナリ フィールド、またはデータ取得ルールをトリガーするディクショナリやディクショナリ フィールドを削除/変更することはできません。まず、関連付けを削除する必要があります。 この検査は、JavaScript 関数に対しては実行されません。 フォームを変更するたびに、そのフォームを組み込むすべてのサービス定義のバージョン番号が、アプリケーションによって自動的に更新されます。 フォームが多数のサービス内で使用されている場合、このような変更の保存にわずかな遅延が生じる場合があります。 また、Requisition API(RAPI)SubmitRequest 操作では、指定するサービスのバージョン番号が必要となるため、サービスをオーダーするために実装されたすべての RAPI プログラムに影響を与える場合があります。
- SQL エントリ データ取得ルールのコーディング:SQL に詳しくない場合は、SQL エントリ データ取得ルールのコーディングが若干難しいかもしれません。 SQL に詳しくなる「秘訣」は、データベース テーブル ルックアップとしてより単純なバージョンのルールの設定から始めることです。 ルールを保存した後、生成した SQL がルールの概要に表示されます。 SQL ステートメントをコピーして SQL 入力データ取得ルールに貼り付け、必要に応じて修正できます。
- カスタマーおよび発信者の Lightweight 名前空間の使用:#Customer# および #Initiator# の Lightweight 名前空間は、Customer-Initiator フォーム コンポーネントで使用される Customer_Information ディクショナリおよび Initiator_Information ディクショナリのフィールドに、デフォルト値として自動的に提供されます。 ただし、これらの名前空間は、すべてのフォーム コンポーネントでデフォルト値として使用できます。
カスタマー ロケーションに関する情報を保持するディクショナリの設計には、この技法を使用できます。 カスタマー ロケーションに関するフィールドは、Customer_Information ディクショナリに含めることができます。 ただし、このようなフィールドを必要とするサービスは、サービスをカスタマーの物理的な場所に提供する必要がある場合などに限定されており、非常に少数です。 より柔軟な設計では、カスタマー ロケーションに対して個別のディクショナリ(およびフォーム コンポーネント)を設定し、このフォーム コンポーネントをカスタマー ロケーションに関係するサービスにのみ含めます。
複数の名前空間をデフォルト値として指定できます。 たとえば、#Customer.FirstName# #Customer.LastName# という式は、カスタマーの姓と名前を 1 つのスペースで区切って連結します。 この式は、個人ベースのディクショナリの最初のフィールドの外観を複製します。
(注) |
Lightweight 名前空間のグリッド ディクショナリ フィールドの使用は、現在サポートされていません。
|