ServiceNowのScript Includeとは何か

開発・導入

サーバーサイドスクリプトの中でも奥が深いScript Includeについて解説します。クライアントサイドスクリプトからScript Includeを呼び出すための仕組みであるGlide Ajaxについても解説します。

Script Includeとは

Scriptingの全体像

Script Includeの前に、ServiceNowにおけるスクリプティングの基本が怪しい方はまずはこちらをご覧ください。これを前提として、Script Includeについて説明していきます。

Script Includeの基本的なイメージ

Script Includeはクラスライブラリのようなもので、処理をパッケージ(部品)化し、複数のサーバーサイドスクリプトから利用できるようにしたものです。

複数のサーバーサイドスクリプトで使われる汎用的な処理があれば、Script Include定義することで一か所にまとめることができます。

Business RuleやUI Actionなどでコードが長くなった場合に、複数の個所から使われ汎用的な処理ではなくてもコードの見通しをよくするために処理をScript Includeに書くこともあります

Client-callable(クライアントからの呼び出しが可能な) Script Includeのイメージ

Script Includeはサーバーサイドのスクリプトですが、クライアントサイドから呼び出せるように作ることも可能です。少し難しいので、なぜこれが必要なのか、というところから順に解説していきます。

Script Includeを必要としないクライアントサイドスクリプトでは、クライアントサイド=ブラウザ=画面上の情報のみを使って処理・制御を行います。具体歴な例としては「Order No.項目が入力されたとき、桁数をチェックし、条件を満たさない場合はエラーを出す」といった制御が該当します。

クライアントサイドで完結するクライアントサイドスクリプトの例

しかし、クライアントサイド=ブラウザ=画面上の情報だけでは処理・制御ができない場合があります。例えば、「Applicant項目が入力されたとき、ユーザが所属する部署の部長をManager項目に自動で設定する」という処理をしたいときは、サーバーサイド=インスタンスにあるユーザ情報を参照する必要があります

サーバーサイドの情報が必要なクライアントサイドスクリプトの例

このような場合に活用するのがClient callable(クライアントからの呼び出しが可能な)Script Includeです。クライアントサイドスクリプトで必要になる情報を取得するサーバーサイドの処理をScript Include(Client callable)で書いておき、これをクライアントサイドスクリプトからGlideAjax APIを用いて呼び出すことで、クライアントサイドでサーバサイドの情報を用いた処理を行うことができるようになります

サーバーサイドの情報が必要なクライアントサイドスクリプトの例

Script Include(not Client callable)の設定・使い方

まずは、サーバーサイドスクリプトから呼び出す基本的なScript Includeについて、設定・使い方を見ていきます。一つのScript Includeは一つのクラス(API)に対応しており、その中に処理を関数として定義します。

設定

この場合の設定はとても簡単です。

  1. メニュー > System Definition > Script Includesを開く
  2. ”New”ボタンを押下して新規レコードを作成する
  3. “Name(名前)”項目を入力する
  4. 自動生成されたクラス定義のコード中に、処理を関数として定義する
  5. 保存する
Script Includeの作り方
var MyScriptInclude = Class.create();
MyScriptInclude.prototype = {
    initialize: function() {
    },
	
	myfunc: function(arg1, arg2) {
		return arg1 + arg2;
	},

    type: 'MyScriptInclude'
};

使い方

使うときは、サーバーサイドスクリプト内でScipt Includeで定義されたクラス(API)をインスタンス化し、クラスメソッドとして処理を呼び出します。メニュー > Scripts – Backgroundに張り付けて呼び出してみましょう。

var msi = new global.MyScriptInclude();
var result = msi.myfunc('bar', 'foo');
gs.info(result);

Script Includeは”Name(名前)”ではなく、”API Name(API名)”で指定します。Script Includeと呼び出し側の処理が同じスコープ内であればNameのみでスコープ部分(上述の例だと”global.”)は不要ですが、スコープが異なる場合はスコープを付与する必要があるため、常に”API Name(API名)”で指定することをお勧めします。

Script Include(Client callable)の作り方・使い方

(その前に…)GlideFormのgetReference()で対応できる場合もある

クライアントサイドスクリプトから呼び出すためのClient callableなScript Includeの設定・使い方の前に、一点知っておくべきことは、クライアントからサーバの情報を取得する際に、必ずしもClient callable Script Includeを使う必要はなく、getReference()を用いることでもっと簡単に実現できるかもしれないということです。

クライアントサイドスクリプトのAPIであるGlideForm(g_form)にはgetReference()という関数があり、こちらはReference項目の参照先のレコードの情報を取得してくる関数です。この関数を利用することで、次のようなシンプルな要件であれば、わざわざClient callable Script Includeを使わなくても実現できます。

getReference()で対応可能なサーバーサイドの情報が必要なクライアントサイドスクリプトの例

単純にReference型項目のレコードで情報の取得ができないような場合について、クライアントサイドスクリプトから呼び出すためのClient callableなScript Includeついて、設定・使い方を見ていきます。

設定

基本的な流れは同じですが、2か所注意が必要です。

  1. メニュー > System Definition > Script Includesを開く
  2. ”New”ボタンを押下して新規レコードを作成する
  3. “Name(名前)”項目を入力する
  4. “Client callable”項目にチェックを入れる
  5. 自動生成されたクラス定義のコード中に、処理を関数として定義する。この際、引数はgetParameter()で取得し、戻り値は文字列で返す(オブジェクトの場合はJSON文字列に変換する)
  6. 保存する
    ※ この際、呼び出し可能なユーザのロールの指定が必要
Client acllable Script Includeの作り方

注意が必要な2か所3点について、補足します。

4. “Client callable”項目にチェックを入れる

クライアントサイドスクリプトから呼び出す場合は、”Client callable”項目にチェックを入れます。これにより、自動で生成されるクラス定義が、クライアントから呼び出しをするための基本的な処理を含む”AbstractAjaxProcessor”クラスを継承するように変更されます

一点注意が必要なのは、“Client callable”項目にチェックを入れることで自動生成されるクラス定義のコードが変更されるのは新規のフォームを開いているときだけで、一度Script Includeを保存した後でチェックを入れてもクラス定義のコードは変更されません

よくあるミスとして、一度通常のScript Includeとして保存した後で、”Client callable”項目にチェックを入れ忘れたことに気が付き後でチェックを入れたが、クラス定義が変更されておらず何度やってもクライアントサイドスクリプトから呼べない、というミスがあります

5. 処理を定義する関数において、引数はgetParameter()で取得する

クライアントサイドスクリプトから呼び出される関数は、通常の括弧の中で引数を指定する形式で引数を取得することができず、次のようgerParameter()取得します

var MyClientCallableScriptInclude = Class.create();
MyClientCallableScriptInclude.prototype = Object.extendsObject(AbstractAjaxProcessor, {

    serverFunc: function(/* この中には引数を定義しない */) {
        var arg1 = this.getParameter('sysparm_arg1'); // 引数"sysparm_arg1"を取得
        var arg2 = this.getParameter('sysparm_arg2'); // 引数"sysparm_arg2"を取得
		return arg1 + arg2;
    },

    type: 'MyClientCallableScriptInclude'
});

また、getParameter()にはさらに細かい注意が一点あり、この関数はjavasriptのStringではなく、JavaのStringオブジェクトを返すため型変換をしないとバグる可能性があります。この件は少しマニアックなので、別記事にまとめました。

5. 処理を定義する関数において、戻り値は文字列で返す(オブジェクトの場合はJSON文字列に変換する)

クライアントサイドスクリプトに情報を返すときは、文字列しか返すことができません。そのため、オブジェクトを返したい場合はJSON.stringify()でJSON文字列に変換してから返します

var MyClientCallableScriptInclude = Class.create();
MyClientCallableScriptInclude.prototype = Object.extendsObject(AbstractAjaxProcessor, {

    serverFunc: function( /* この中には引数を定義しない */ ) {
        var arg1 = this.getParameter('sysparm_arg1'); // 引数"sysparm_arg1"を取得
        var arg2 = this.getParameter('sysparm_arg2'); // 引数"sysparm_arg2"を取得
        var result = { // クライアント側に返したいオブジェクト
            'arg1': arg1,
            'arg2': arg2
        };
        return JSON.stringify(result); // JSON文字列に変換してから返す
    },

    type: 'MyClientCallableScriptInclude'
});

なお、クライアントサイドではJSON.parse()でオブジェクトに復元します。

// answer変数に結果を格納
var result = JSON.parse(answer);

使い方(GlideAjax APIを利用)

クライアントサイドスクリプトからClient callabl Script Includeを呼び出すためには、クライアントサイドのAPIであるGlideAjaxを利用します。

GlideAjaxの使い方についてはこちらは下記の記事で説明しています。

(補足)Global Business Ruleについて

標準の機能を調べていると、たまにScript Includeではなく、Business Ruleに定義された関数を他のサーバーサイドスクリプトが参照していることがあると思います。

これは、Global Business Ruleと呼ばれており、Script Includeがまだ無かった時代に、複数のサーバーサイドスクリプトから共通で呼び出す関数を定義するために使われていました。

今では基本的にScript Includeが使われていますが、かなり昔からある機能は、未だにGlobal Business Ruleで実装されているものもあります。

以上です。

コメント

タイトルとURLをコピーしました