Scripted REST API の例 - ストリーミングとオブジェクトの直列化
これらの例は、ストリーミングとデフォルトオブジェクトの直列化を使用して JSON 応答を送信する方法を示しています。
ストリーミングとオブジェクトの直列化
応答を送信するときは、応答をストリームとして送信するか、オブジェクトを直列化できます。どちらのアプローチにも長所と短所があります。統合のニーズに基づいて手法を選択してください。
一般に、応答オブジェクトがシンプルであり、XML または JSON として表現でき、サイズが一貫している場合は、オブジェクトの直列化を使用します。XML または JSON 以外の形式を使用する場合、または応答のサイズが異なる場合は、ストリーミングを使用します。
応答のストリーミング
応答のストリーミングを使用すると、応答時間、インスタンスのパフォーマンス、およびコンテンツの柔軟性が向上しますが、スクリプトが複雑になります。ストリーミングを使用する場合は、応答の書式設定、応答ステータスの設定、および Content-Type ヘッダーの設定を行う必要があります。応答をストリーミングする場合、ストリーミングを開始する前に応答全体を作成する必要がないため、要求ユーザーはすぐに応答を受信します。
この例は、ストリーミングを使用してインシデントレコードのアレイを返すスクリプト化された REST リソーススクリプトを示しています。
/**
* Sample Scripted REST Resource that returns custom JSON objects with properties from Incident GlideRecords
* This sample uses ServiceNow JavaScript API to query incident records
* and then iterates over those records to build and stream a custom JSON object that
* includes some values from the incidents
*/
(function runOperation(/*RESTServiceRequest*/ request, /*RESTServiceResult*/ response) {
var writer = response.getStreamWriter(),
hdrs = {},
table = 'incident',
record_limit = 100,
gr = new GlideRecord(table);
hdrs['Content-Type'] = 'application/json';
response.setStatus(200);
response.setHeaders(hdrs);
gr.setLimit(record_limit);
gr.query();
// start building response object
writer.writeString("{\"results\":[");
// iterate over incident records and build JSON representations to be streamed out.
while (gr.next()) {
var incidentObj = {};
incidentObj.number = gr.number + '';
incidentObj.short_description = gr.short_description + '';
writer.writeString(global.JSON.stringify(incidentObj));
if (gr.hasNext()) {
writer.writeString(",");
}
}
// close the response object
writer.writeString("]}");
})(request, response);
このリソースへの要求は、次の応答を返します。
// sample response
/*
HTTP/1.1 200 OK
Content-Type: application/json
Server: ServiceNow
// sample response number of records returned has been truncated for this example
{
"results": [
{
"number": "INC0011301",
"short_description": "lorem ipsum short description 0 my new incident"
},
{
"number": "INC0011302",
"short_description": "lorem ipsum short description 1 my new incident"
},
{
"number": "INC0011303",
"short_description": "lorem ipsum short description 2 my new incident"
},
{
"number": "INC0011304",
"short_description": "lorem ipsum short description 3 my new incident"
},
{
"number": "INC0011309",
"short_description": "lorem ipsum short description 8 my new incident"
},
{
"number": "INC0011310",
"short_description": "lorem ipsum short description 9 my new incident"
},
{
"number": "INC0011311",
"short_description": "lorem ipsum short description 0 my new incident"
},
{
"number": "INC0011312",
"short_description": "lorem ipsum short description 1 my new incident"
},
{
"number": "INC0011313",
"short_description": "lorem ipsum short description 2 my new incident"
},
{
"number": "INC0011314",
"short_description": "lorem ipsum short description 3 my new incident"
},
{
"number": "INC0011315",
"short_description": "lorem ipsum short description 4 my new incident"
},
{
"number": "INC0011326",
"short_description": "lorem ipsum short description 15 my new incident"
}
]
}
*/
ストリーミングページネーション
クエリごとに限られた数のレコードのみを送信するように大きなテーブルをページネーションするには、この スコープ対象/グローバル GlideRecord - chooseWindow(数値 firstRow, 数値 lastRow, ブーリアン forceCount) メソッドを使用します。コミュニティ記事「 ページネーションされた Glide レコード + 展開された GR メソッドのサポート 」は、 chooseWindow() を使用してページネーションを実現する方法を示しており、特定のユースケースに適応させることができます。
オブジェクトの構築
オブジェクトの直列化を使用すると、ServiceNow が提供する直列化とコンテンツネゴシエーションを利用できます。ストリーミングではなくオブジェクトを直列化する場合は、クライアントが応答を受信する前にオブジェクト全体を作成して直列化する必要があります。これにより、応答が遅延するか、応答オブジェクトが非常に大きい場合は大量のシステムリソースが必要になる可能性があります。オブジェクトの直列化は XML または JSON 応答でのみ使用できます。別の形式を使用する応答では、ストリーミングを使用する必要があります。
この例は、ストリーミングの例と同じインシデントデータを返しますが、応答を送信する前にすべての応答データをアレイに収集します。
/**
* Sample Scripted REST Resource returns an array of custom JSON objects that include 2 incident properties.
* This sample uses ServiceNow JavaScript API to query incident records and then iterates
* over those records building a custom JSON object that includes 2 values from the incident records.
* note that because we are returning a simple JSON object we can rely on built in serialization
* to set the content-type header as well as response status. The 'result_arr' object will not be returned
* until it has been completely built and stored
*/
(function runOperation(/*RESTServiceRequest*/ request, /*RESTServiceResult*/ response) {
var table = 'incident',
record_limit = 100,
result_arr = [],
gr = new GlideRecord(table);
gr.setLimit(record_limit);
gr.query();
// iterate over incident records and build JSON representations to be streamed out.
while (gr.next()) {
var incidentObj = {};
incidentObj.number = gr.number + '';
incidentObj.short_description = gr.short_description + '';
result_arr.push(incidentObj);
}
return result_arr;
})(request, response);
このリソースへの要求は、次の応答を返します。
/*
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Server: ServiceNow
// sample response number of records returned has been truncated for this example
{
"result": [{
"short_description": "lorem ipsum short description 0 my new incident",
"number": "INC0011301"
}, {
"short_description": "lorem ipsum short description 1 my new incident",
"number": "INC0011302"
}, {
"short_description": "lorem ipsum short description 2 my new incident",
"number": "INC0011303"
}, {
"short_description": "lorem ipsum short description 3 my new incident",
"number": "INC0011304"
}, {
"short_description": "lorem ipsum short description 4 my new incident",
"number": "INC0011305"
}, {
"short_description": "lorem ipsum short description 5 my new incident",
"number": "INC0011306"
}, {
"short_description": "lorem ipsum short description 6 my new incident",
"number": "INC0011307"
}, {
"short_description": "lorem ipsum short description 7 my new incident",
"number": "INC0011308"
}, {
"short_description": "lorem ipsum short description 8 my new incident",
"number": "INC0011309"
}, {
"short_description": "lorem ipsum short description 9 my new incident",
"number": "INC0011310"
}]
}
*/