メインコンテンツへスキップ
見出し画像

独自エンドポイントを自分で作る(Scripted REST API)


    ServiceNow に外部システムからデータを出し入れするとき、まず使うのが標準の Table API(/api/now/table/{table})です。これはテーブル単位の汎用 CRUD で、定義なしにそのまま使えます。一方で「複数テーブルをまとめて返したい」「独自の URL とレスポンス形式にしたい」という場面では、自分で API を定義する Scripted REST API が登場します。

    この記事では、REST 連携を機能論だけで説明しません。実際の sys_ws_definition(Service)と sys_ws_operation(Resource)という2テーブルが起点です。PDI(Zurich)の OOTB で確認した実測値を、この記事で示します。

    この記事は、ServiceNow の Incident や Table API は触ったことがあるが、Scripted REST API のテーブル構造をこれから理解したい管理者・開発者向けです。実機では、どこに何が保存され、どう公開URLが決まるかを、サービスとリソースの継承・主要フィールド・http_method・認証フラグの順で確認します。

    この記事で分かること

    • 標準 Table API と Scripted REST API の役割の違い(汎用 CRUD vs 独自エンドポイント)

    • Scripted REST が Service(sys_ws_definition)→ Resource(sys_ws_operation)の1:N で構成されること

    • 公開URLが base_uri + relative_path で組み立てられること

    • sys_ws_operation がどんなフィールドを持つか(処理本体は operation_script)

    • http_method(5値)の OOTB 実測分布(GET / POST が大半)

    • 認証・ACL の入口(requires_authentication / requires_acl_authorization)

    • 実機で確認するときに見るべき一覧URL

    この記事の内容は ServiceNow の PDI(Personal Developer Instance)Zurich(ズーリッヒ)リリースの OOTB(初期設定)で確認した個人メモです。本番環境やカスタマイズ済み環境では、サービス構成・フィールド・件数の内容が異なる場合があります。


    Scripted REST API とは

    ServiceNow の REST 連携には、大きく2つの入口があります。1つは標準の Table API で、/api/now/table/{table} の形で任意のテーブルを汎用的に CRUD できます。定義は不要で、テーブルと権限さえあればすぐ使えます。もう1つが Scripted REST API です。開発者が「独自の URL」「独自のリクエスト/レスポンス」「独自のサーバ側処理」を持つ REST エンドポイントを、自分で定義する仕組みです。

    その定義を格納する中心テーブルが sys_ws_definition(画面ラベルは Scripted REST API)です。その下にぶら下がるのが sys_ws_operation(画面ラベルは Scripted REST Resource)です。1つのサービス(Service)に、複数のリソース(Resource)が紐づきます。

    Table API は「テーブルをそのまま公開する汎用 API」であるのに対し、Scripted REST API は「自分で書いた処理を公開する独自 API」です。Qiita などの解説でも、Scripted REST API は「Table API では1回で1テーブルしか返せない」という制約を超え、複数テーブルを集約・整形して返す用途で紹介されています。


    画像

    今回確認した PDI(Zurich / OOTB)では、sys_ws_definition(Service)は 225 件でした。sys_ws_operation(Resource)は 1,158 件 です。OOTB の時点で、ServiceNow 自身が多数の Scripted REST API を内部利用していることが分かります。


    画像

    Service と Resource の関係(継承とリンク)

    Scripted REST API に関係するテーブルは、「サービス」「リソース」「バージョン」の3つに分けて見ると整理できます。


    画像

    実機の PDI(Zurich / OOTB)では、それぞれ次の構造でした。

    • sys_ws_definition(Service) … super_class は sys_metadata(Application File)でした。task は継承していません。固有フィールドは 15 です。

    • sys_ws_operation(Resource) … こちらも sys_metadata(Application File)を継承していました。固有フィールドは 20 です。

    • リンク … Resource の web_service_definition(API definition)は、親の sys_ws_definition を指します。あわせて web_service_version(API version)が sys_ws_version(今回の PDI で71件)を参照します。

    Service の内訳(namespace・バージョニング)

    225件の Service のうち、namespace=now(標準の ServiceNow 名前空間)は97件でした。残りは各アプリ固有の namespace です。また、API バージョニングに対応する(is_versioned=true)Service は69件でした。

    つまり、Service と Resource はどちらも「メタデータ(設定)」のテーブルで、task のような業務レコードではありません。1つの Service の下に、メソッド違い・パス違いの Resource が複数ぶら下がるのが基本構造です。

    なお、標準 Table API はこの sys_ws_definition には登録されていません(service_id=table のレコードは0件でした)。Table API は OOTB のシステム Web サービスで、Scripted REST API とは別物です。この記事で扱う2テーブルは、あくまで「自分で定義する側」の入れ物です。

    テーブル定義は、次のURLで確認できます(先頭の <YourInstance> は自分のインスタンスに置き換えてください)。

    https://<YourInstance>/sys_ws_definition_list.do?sysparm_query=active=true^ORDERBYname

    公開URLの組み立て(base_uri + relative_path)

    Scripted REST API では、公開される URL がどこで決まるかを押さえておきます。URL は1つのフィールドではなく、Service 側と Resource 側の2つを足し合わせて決まります。


    画像

    組み立ては次の関係でした。

    • Service(sys_ws_definition)の base_uri … /api/<namespace>/<service_id> の形。例として TimeAgo サービスは namespace=now、service_id=timeago で、base_uri = /api/now/timeago でした。

    • Resource(sys_ws_operation)の relative_path … base_uri に続く相対パス。TimeAgo の absolute リソースは http_method=GET、relative_path=/absolute でした。

    • 公開URL = base_uri + relative_path です。例えば /api/now/timeago/absolute を GET で叩くと、そのリソースが呼ばれます。呼ばれた先では、operation_script の process(request, response) が動きます。

    「HTTP メソッド × パス」で1つの Resource が特定されます。同じパスでも GET と POST で別の Resource を用意できますし、/record/{id} のようにパス変数(path params)を含めることもできます。下の実画面は、TimeAgo サービスの Service フォームです。base_uri と、紐づく Resource の一覧(Resources 関連リスト)が確認できます。


    画像

    実際の Resource フォームでは、http_method・relative_path・operation_script(処理本体)がまとまっています。


    画像

    公式の Scripted REST APIs(Zurich) に、Scripted REST Service と Resource の関係、base path とリソースパスの組み立て方が説明されています。


    Resource の主なフィールド

    sys_ws_operation は、「どのメソッド・どのパスで・どんな処理を・どんな権限で」公開するかを表す項目を持ちます。役割で分けると、識別/公開先・親への参照・処理・入出力形式・認証/権限に整理できます。


    画像

    役割ごとの主なフィールド名

    • 識別・公開先:name, http_method, relative_path, operation_uri, default_operation_uri

    • 親への参照:web_service_definition, web_service_version

    • 処理:operation_script

    • 入出力形式:consumes, produces, consumes_customized, produces_customized

    • 認証/権限:requires_authentication, requires_acl_authorization, requires_snc_internal_role, enforce_acl

    主なフィールドの代表は次のとおりです。ラベルは画面上の表示名で、実機どおり記載します。


    画像

    処理本体は operation_script に process(request, response) 関数として入っています。Business Rule のように「保存時に副次的に動く」のではなく、REST リクエストが来たときに直接呼ばれる入口になります。request からクエリ・本文・ヘッダを読み、response に結果を書きます。

    また、web_service_definition(API definition)で親サービスを必ず指す点も重要です。Resource は単独では存在せず、必ずどこかの Service にぶら下がります。

    consumes / produces の既定値

    入出力形式を持つ consumes / produces の既定値は、application/json・application/xml・text/xml でした。JSON だけでなく XML 系も標準で受け付ける設定になっています。

    全フィールドは、次のURLで一覧できます。

    https://<YourInstance>/sys_dictionary_list.do?sysparm_query=name=sys_ws_operation^elementISNOTEMPTY


    画像

    HTTP メソッド(http_method)

    各 Resource は、どの HTTP メソッドで呼ばれるかを http_method で持ちます。これは task 系の State のような業務状態ではなく、REST の動詞です。

    実測では、PDI(Zurich / OOTB)の sys_ws_operation.http_method は次の5値でした(value = label, sequence順)。


    画像

    OOTB の全 1,158 リソースで分布を取ると、GET が 638、POST が 413 と、この2つで約91%を占めました。PATCH 41・DELETE 34・PUT 32 は少数です。一般的な REST の慣習は、GET=取得・POST=作成や処理起動・PUT=置換更新・PATCH=部分更新・DELETE=削除です。ただし Scripted REST では処理を自分で書くため、必ずしもこの慣習どおりとは限りません(POST で取得処理を書くことも技術的には可能です)。

    注意したいのは、同じパスでもメソッドが違えば別の Resource になる点です。だから「どのリソースが呼ばれるか」は、URL だけでなく HTTP メソッドとセットで決まります。

    http_method の選択肢は、次のURLで一覧できます。

    https://<YourInstance>/sys_choice_list.do?sysparm_query=name=sys_ws_operation^element=http_method^inactive=false^ORDERBYsequence


    画像

    認証と ACL の入口

    外部に口を開ける以上、Scripted REST API は「誰が呼べるか」を制御します。Resource は、認証と権限に関わる入口のフラグを持っていました。

    今回確認した PDI(Zurich / OOTB)では、次の傾向でした。

    • requires_authentication(Requires authentication) … 既定 true。匿名許可(false)のリソースは 1,158 件中 26 件だけで、残りは認証必須でした。つまり大半は「ログイン(または OAuth / Basic 等)が前提」です。

    • requires_acl_authorization(Requires ACL authorization) … true が 1,038 件。多くのリソースで ACL チェックが有効になっており、enforce_acl(ACLs → sys_security_acl)で適用する ACL を指定できます。

    • requires_snc_internal_role(Requires ServiceNow internal role) … ServiceNow 内部ロールを要求するフラグ。認証・権限は、この3つのフラグの組み合わせで制御されています。

    Scripted REST API の権限は、認証(誰であるか)と ACL(そのデータを操作してよいか)の2段で考えます。requires_authentication で入口を絞り、requires_acl_authorization + enforce_acl でレコード/フィールド単位の権限を効かせます。匿名公開(requires_authentication=false)は少数派で、OOTB でも限定的に使われていました。実環境で外部公開する場合は、この2つを意識して設定する必要があります。

    公式の Scripted REST APIs good practices(Zurich) に、認証・ACL・エラーハンドリングなど Scripted REST API を作るときの推奨事項が説明されています。


    Scripted REST API に関わる周辺機能

    Scripted REST API の動きも、フィールド定義だけでは決まりません。保存時の処理や権限など、複数の設定が組み合わさって動きます。大まかには、保存時の処理は Business Rule、操作は UI Action、権限は ACL が関係します。

    実機の PDI(Zurich / OOTB・active 中心・2026-06-20 確認)では、Service / Resource に次のような設定が紐づいていました。


    画像

    注意したいのは、ここで数えているのは sys_ws_definition / sys_ws_operation という「定義テーブル」に直接紐づく設定だけという点です。実際の API の挙動は、各 Resource の operation_script の中身と、その先で呼ばれる Business Rule・ACL・データ側の設定が合わさって決まります。定義テーブルの周辺設定だけを見て、API 全体のセキュリティや動作を判断しないようにします。

    自分のインスタンスでは、次のURLで各一覧を開けます(先頭の <YourInstance> は置き換えてください)。

    Resources(全件) : https://<YourInstance>/sys_ws_operation_list.do?sysparm_query=active=true^ORDERBYname
    Business Rules    : https://<YourInstance>/sys_script_list.do?sysparm_query=collection=sys_ws_operation
    Access Controls   : https://<YourInstance>/sys_security_acl_list.do?sysparm_query=name=sys_ws_operation

    ServiceNow における Scripted REST API のポイント

    • REST 連携の入口は2つ。標準 Table API(汎用 CRUD・定義不要)と、Scripted REST API(自分で定義する独自エンドポイント)です。Table API は sys_ws_definition には登録されていません(別物)。

    • Scripted REST は sys_ws_definition(Service)→ sys_ws_operation(Resource)の1:N で構成されます。どちらも Application File(sys_metadata)を継承する定義テーブルで、固有フィールドは Service 15・Resource 20 でした。

    • 公開URLは base_uri(/api/<namespace>/<service_id>)+ relative_path で決まります。「HTTP メソッド × パス」で1つの Resource が特定され、処理本体は operation_script の process(request, response) です。

    • 今回の PDI では Service 225 件・Resource 1,158 件。http_method は GET 638 / POST 413 で約91%を占めました。

    • 権限は 認証(requires_authentication・既定 true)と ACL(requires_acl_authorization / enforce_acl)の2段。匿名許可は 1,158 件中 26 件と少数派でした。

    Scripted REST API を調べるときは、まず URL から Service(base_uri)と Resource(method+path)を特定します。そのうえで Resource 単体ではなく、上の Service、横の operation_script、そして認証・ACL をセットで確認します。


    実機を見て気づいたこと

    • Service 225件・Resource 1,158件を単純に割ると、1 Service あたり平均約5 Resource でした。TimeAgo のように数個だけのサービスもあれば、もっと多くのエンドポイントを抱えるサービスもあり、規模はまちまちです。

    • 認証・権限のフラグは requires_authentication と requires_acl_authorization の2つだと思っていましたが、requires_snc_internal_role という3つ目のフラグもありました。外部公開の可否だけでなく、ServiceNow 内部ロールを要求するという別軸の制御が用意されています。


    次に読むなら

    次に確認するとよいのは、次のあたりです。

    • operation_script の request / response オブジェクトの使い方(クエリ・本文・ヘッダの読み取り、ステータスコードの返し方)

    • パス変数(path params)とクエリパラメータの取り回し

    • REST API Explorer での実行確認

    特に「定義(テーブル構造)」と「処理(operation_script)」を分けて理解すると、外部連携が動かないときの切り分けが一気に楽になります。これらは本記事の「公開URLの組み立て」「Resource の主なフィールド」で触れた仕組みの先にあたり、別記事で扱う予定です。


    用語

    • PDI:Personal Developer Instance(無料の検証用インスタンス)

    • OOTB:Out of the Box(初期設定のまま)

    • Table API:/api/now/table/{table} の標準 REST API(テーブル汎用 CRUD・定義不要)

    • Scripted REST API:開発者が定義する独自 REST エンドポイント(Service + Resource)

    • Service(sys_ws_definition):1つの Scripted REST API(base_uri を持つ)

    • Resource(sys_ws_operation):Service 配下の1エンドポイント(method+path+script)

    • base_uri:/api/<namespace>/<service_id> の公開ベースパス

    自分の環境で確認するときのURL

    先頭に自分のインスタンスを付けると、同じ画面が開けます。

    Service 一覧   : sys_ws_definition_list.do?sysparm_query=active=true^ORDERBYname
    Resource 一覧  : sys_ws_operation_list.do?sysparm_query=active=true^ORDERBYname
    フィールド一覧 : sys_dictionary_list.do?sysparm_query=name=sys_ws_operation^elementISNOTEMPTY
    http_method   : sys_choice_list.do?sysparm_query=name=sys_ws_operation^element=http_method^inactive=false^ORDERBYsequence
    テーブル定義   : sys_db_object_list.do?sysparm_query=name=sys_ws_definition^ORname=sys_ws_operation

    検証範囲とおことわり

    • 確認した範囲:PDI(Zurich / 2026-06-20 確認)の OOTB で、以下を取得しています。

    • sys_ws_definition / sys_ws_operation の階層(Application File 継承)

    • 固有フィールド数(Service 15 / Resource 20)

    • http_method の選択肢(5値)と分布

    • 主要フィールドと参照先(web_service_definition / web_service_version / operation_script)

    • レコード件数、認証・ACL フラグの件数、周辺設定件数

    • 公開URLの組み立て例

    • 確認していない範囲(断定しません。これらは別記事で扱います)

    • 各 operation_script の中身

    • REST API Explorer の動作

    • OAuth / Basic / API Key など認証方式ごとの挙動

    • レート制限・ペイロード上限

    • Table API 側のクエリパラメータ詳細

    • 本番でのカスタムサービスのセキュリティ設定

    今回は PDI の OOTB(初期設定)を前提に、Scripted REST API の構造を確認しました。実環境では、既存のカスタマイズによってサービス・リソースの数や設定の内容が変わります。

     
     
    ServiceNowのPDI(Personal Developer Instance)を実機で観察して、Noteに記事を書いています 実装・運用・教育の現場視点で淡々と記録中です リクエストがあればその記事も書きます 個人の観察日記です

    あなたへのおすすめ