ServiceNow GraphQL: スキーマ公開する (準備としてカスタムアプリ作る)
スキーマ公開はIncidentを使おうかと思いましたが、もう少しコンパクトにカスタムアプリでやってみようと思います。
全データ公開とかカジュアルにやりたいのですが、incidentではデータ量が多すぎる。
アプリケーションを作る
スコープアプリと言って、固有のネームスペースを区切って共通部分や他のアプリケーションとは別に扱えるようにしたものを作ります。
一個のマイクロサービスのようなものと思ってください。
App Engine Studioなるものもあり、Excelからテーブルを起こすことができるように見えて便利そうですが、今回はただのStudioを使います。
画面左のナビゲーションの検索フィールドにstudioと入力、結果のうちSystem Applications > Studioをポチ。
[Create Application] をポチ。
[Let's get started] をポチ。
よしなに埋めます。
Advanced SettingsのところはScopedにします。スコープアプリ (Scoped Application) を作るからです。
最後に右下の [Create] をポチ。
次の画面はこのアプリにアクセスするユーザーのロールを作成します。
既存ロールを使ってもいいですが、今回はロールを新しく一つ作成することにします。
Create new roleから任意のロール名を指定し、左下の[Continue] をポチ。
どちらの画面を作りますかと聞かれたのでお好みの方を選んで [Continue] をポチ。以下の図は両方選んだところ。
テーブルは既存のものを使うかどうかと聞かれたので、白いボタンの [Create new table] をポチ。
Excelのアップロード、既存テーブルの拡張、新規作成があります。ここは新規作成 (Create table from scratch) を選択して [Continue] をポチ。
とりあえずこんな感じに作ってみます。メインのテーブルはmybooks, 参照先のテーブルはauthorsとpublishersがあります。
ちなみに作成するときは参照先のテーブルの方から作った方が面倒くさくなくていいです。メインのテーブルで参照フィールドを作成するとき、参照先テーブルがないと作れないのです。
[Add a new field] をポチ。
入力フィールドに必要事項を入力します。
見当たらないフィールドは右の赤枠の部分をクリックすると表示されます。
Field Label: 画面上のラベル名
Field name: フィールド名、DBテーブルの方に使うやつ
Field Type: データ型
Character Limit: 長さ
Display: 画面に表示するかどうか
Mandatory: 必須項目かどうか
必要なものが全部できたら右下の [Continue] をポチ。
Table labelにテーブルの名前をつけます。
ここではIDを自動採番にしたいので、Auto-numberにチェックをつけます。
よろしければ [Continue] をポチ。
ちなみにIDであるNumber属性は指定しなくても勝手に作ってくれました。
注: 諸事情によりこのスクショとった後テーブルを「books」として作り直してます。
少し時間が経って成功 (Success) と出るので、[Continue] を押すとこの画面に戻りますので必要なものを作ります。
作り終わったら [Done with tables] をポチ。
アプリケーションのカスタマイズができる画面が出ます。特にカスタマイズはしないので、[Start] で選択して内容確認、[Create] をポチ。
二つとも終わったら [Done with Apps] をポチ。
そろそろおしまいです。[Done] をポチ。
ここで一段落。
念のためStudio画面を開いておきたいです。
作成したアプリをポチ。
もしフィールドの追加作成が必要ならStudioからできます。
データを適当に作る
Studioは別タブで開いているはずなので元のServiceNowの画面に戻り、画面をリフレッシュします。
リフレッシュ後は画面左のナビゲーションに今作ったアプリが表示されますので、適当にデータを作成します。
GraphQLのスキーマを設定する
さてここからやっとGraphQLのスキーマです。
Studioの中には設定が見当たらないので、元のServiceNowのUIの方で設定します。
今自分が作業しようとしているスコープがわかるようにする
スコープアプリを作ったんですが、他のアプリケーションとの境界線がはっきりとしています。
このアプリケーションに対してアクセスするようなものを作るには、同じスコープの中に設定を作成するか、あるいは別のスコープや共有エリア (グローバル) に作ってもいいけどそこに対して今回のアプリがアクセス権を許可するようにします。
今回は同じスコープの中に設定を作成します。
という作業をするので、「今自分がどこのアプリケーションスコープにものを作ろうとしているかがわかる」という状態が欲しいです。
画面上にアプリケーションピッカーを表示させましょう。
画面右上の歯車マークをポチ。
左のメニューから [Developer] を選択、右画面で [Show application picker in header] を画像の通りにするとONになります。
画面の歯車マークの並びに自分が今作業しようとしているアプリケーションのスコープが表示されたら完了。
ここが自分のアプリケーションになっているか確認します。
余談ですが本当にアプリケーションを開発する場合は、移行資産のパッケージ (Update Set) の設定のピッカーも表示します。
今回は不要なので割愛。
(やっと) GraphQLのスキーマを作る
設定は次の3点セット。
スキーマ
Scripted Resolver
Resolver Mapping
製品マニュアルにはScripted ResolverはOptionalと書いてあるように見えるのですが、どう考えてもスキーマの記述の段階では特定のテーブルに紐づいていなかったので、スクリプトは書く必要があります。多分。
念のためスキーマのプロパティに存在しないプロパティを指定してみても全くエラーは出なかった。テーブルを指定していないので当たり前です。
そのうち公式さんがマニュアル更新してくれると思います。
Scripted ResolverはDBから取り出したデータをスキーマに渡すために使用します。
スクリプトに使用するライブラリはこちら。
ServiceNowではスクリプトに使用するライブラリもAPIと呼ぶ、少し古いスタイルの「API」という言葉の使い方をするので、APIとはHTTP上を行き来するものと思っていると迷子になります。
statusがavailableな本の一覧を持ってきてみましょう。
クエリ部分。
query {
x805160MyBooks {
mytestschema {
availablebooks {
id
number
name
author
publisher
description
status
}
}
}
}
レスポンス
{
"data": {
"x805160MyBooks": {
"mytestschema": {
"availablebooks": [
{
"id": "156e8e7a1b3ec110b66f55f0604bcba0",
"number": "MYB0001002",
"name": "BASARA",
"author": "田村由美",
"publisher": "小学館",
"description": "",
"status": "Available"
},
{
"id": "3dce86f21b7ec110b66f55f0604bcb57",
"number": "MYB0001004",
"name": "Implementing Domain-Driven Design",
"author": "Vaughn Vernon",
"publisher": "Pearson Education, Inc.",
"description": "\"For software developers of all experience levels looking to improve their results, and design and implement domain-driven enterprise applications consistently with the best current state of professional practice, Implementing Domain-Driven Design will impart a treasure trove of knowledge hard won within the DDD and enterprise application architecture communities over the last couple decades.\"\r\n\r\n–Randy Stafford, Architect At-Large, Oracle Coherence Product Development",
"status": "Available"
},
{
"id": "6bcfcef21b7ec110b66f55f0604bcba0",
"number": "MYB0001005",
"name": "北斗の拳",
"author": "原哲夫",
"publisher": "集英社",
"description": "",
"status": "Available"
}
]
}
}
}
}
ではまずはスキーマ。
プロパティのところですが、コロンの左側がAPIの中で取り扱うプロパティ名で、必ずしもデータベースのスキーマにある情報と一致しなくてもいいものです。右側 @source 以下がスクリプトの中から取り出したフィールドの名前。
schema {
query: Query
mutation: Mutation
}
type Query {
availablebooks: [AvailableBooks]
}
type Mutation {
#implement here...
}
type AvailableBooks {
id: ID! @source(value: "sys_id.display_value")
number: String! @source(value: "number.display_value")
name: String @source(value: "name.display_value")
author: String @source(value: "author.display_value")
publisher: String @source(value: "publisher.display_value")
description: String @source(value: "description.display_value")
status: String @source(value: "status.display_value")
}
ServiceNow固有の部分と思いますが、スクリプトで単純にレコードを取ってくるだけだと、各フィールドの値にvalueとdisplay_valueの2つがあるので、どちらかを選択する必要あり。
スキーマ画面の下、タブ群の中から [GraphQL Scripted Resolver] タブに以下を挿入しました。
コード部分には「x_805160_my_books_mybooksのテーブルからstatus=availableな本の一覧を全フィールド込みでください」と書いてあります。
Studioでテーブル名を指定する時に入力した名前はbooksでしたが、これはラベル扱いになっています。実際には重複を避けるためにシステム内で重複しないテーブル名が付与されており、スクリプトの中ではラベルの方ではなく重複なくつけられたTable nameを指定する必要があります。
(function process( /*ResolverEnvironment*/ env) {
var books = new GlideRecord('x_805160_my_books_mybooks');
books.addQuery('status', 'available');
books.query();
return books;
})(env);
最後にまたタブ群から [GraphQL Resolver Mapping] を登録します。
これはスキーマ内に定義されたavailablebooksフィールドとScripted ResolverのAvailable Resolverの関連付けをしています。
この記事が気に入ったらサポートをしてみませんか?