Skip to content

ApiVersion の決まり方 ​

第2版作成 最終更新 (日本時間)
確認バージョン1.5.8.1

API のリクエストに書く ApiVersion は、レスポンスの形(ClassA のような個別プロパティか、ClassHash のような辞書か)を決めます。ところが Api.json の設定によっては、スクリプトの $p.apiGet などで ApiVersion: 1.1 を指定しても無視され、1.0 形式のまま返ってきます。このページでは、ApiVersion がどこで決まるかと、その回避策をまとめます。

INFO

実装の根拠は、確認時のソースへの固定リンクで示しています。

ApiVersion で変わること ​

API のモデル(_BaseApiModel)は、ApiVersion が 1.1 未満(< 1.100)のときだけ、辞書形式の値を ClassA・NumA・DateA などの個別プロパティに展開して返します。リクエストを読むときも、1.1 未満なら個別プロパティを辞書に詰め直します(_BaseApiModel.cs#L815-L818、_BaseApiModel.cs#L1585-L1588)。

ApiVersionレスポンスの形
1.0"ClassA": "...", "NumA": 1 のように個別プロパティ
1.1"ClassHash": { "ClassA": "..." }, "NumHash": { "NumA": 1 } のように辞書

レスポンスの形を決めるのは、リクエストごとに決まる Context.ApiVersion です。

Context.ApiVersion の決まり方 ​

Context.ApiVersion の初期値は Api.json の Version です(Context.cs#L130)。リクエストボディを Api クラスとして読んだ後、SetApiOptions() がリクエストの値で上書きします(Context.cs#L521-L536)。

csharp
private void SetApiOptions(Api api)
{
    if (Parameters.Api.Compatibility_1_3_12)
    {
        if (api?.ApiKey.IsNullOrEmpty() == false)
        {
            ApiVersion = api.ApiVersion;
        }
    }
    else
    {
        ApiVersion = api?.ApiVersion ?? ApiVersion;
    }
    ApiSsCache = api?.SsCache ?? false;
}

Compatibility_1_3_12 が true のときは、リクエストに ApiKey があるときだけ ApiVersion を反映します。ApiKey のないリクエストは、何を指定しても Api.json の Version のままです。Compatibility_1_3_12 を参照しているのはこの 1 か所だけで、ほかの処理には影響しません。

リクエストで ApiVersion を省略した場合も、Api クラスの初期値が Api.json の Version なので(Api.cs#L11)、結果は Version と同じです。

認証方式ApiKeyCompatibility_1_3_12: trueCompatibility_1_3_12: false
API キー(外部のクライアント)ありリクエストの ApiVersionリクエストの ApiVersion
セッション($p.apiGet などのスクリプト)なし常に Api.json の Versionリクエストの ApiVersion

$p.apiGet で ApiVersion が効かない例 ​

スクリプトの $p.apiGet などは args.data を JSON にして送り、画面の CSRF トークン(Token)を付けてセッションで認証します(_api.js#L64-L86)。ApiKey は送りません。

json
{
    "Version": 1.0,
    "Enabled": true,
    "PageSize": 200,
    "LimitPerSite": 0,
    "Compatibility_1_3_12": true
}

この設定で次のスクリプトを実行すると、ApiVersion: '1.1' は無視され、レスポンスは 1.0 形式(ClassA などの個別プロパティ)になります。

javascript
$p.apiGet({
    id: 12345,
    data: { ApiVersion: '1.1' },
    done: function (data) {
        console.log(data);
    }
});

図を読み込み中…

$p.apiGet に限らず、$p.apiCreate・$p.apiUpdate・$p.apiUsersGet など、セッションで動くスクリプトのラッパーすべてで同じです。

回避策 ​

1.5.8.1 の Api.json の既定値は "Version": 1.1、"Compatibility_1_3_12": false です(Api.json)。古い環境から設定を引き継いでいて true になっている場合は、次のどれかで対処します。

方法設定注意点
互換動作を止める"Compatibility_1_3_12": falseApiKey なしのリクエストでも ApiVersion が効くようになる。ApiVersion を 1.0 と書いているスクリプトがあれば、その指定どおり 1.0 形式で返るようになる
既定のバージョンを上げる"Version": 1.1ApiVersion を省略しているすべての API(外部の連携を含む)のレスポンスが 1.1 形式になる
ApiKey を付けて送るdata に ApiKey を入れる画面のスクリプトに API キーを埋め込むことになるので勧められない

TIP

どれも選べないときは、スクリプト側で 1.0 形式のレスポンスをそのまま扱うしかありません。Compatibility_1_3_12 の条件を外す本体改修の検討は ApiKey なしでも ApiVersion を反映する改修 を参照してください。

関連ページ ​

変更履歴

第2版記事の確認版を繰り返す表現を整理する
第1版サイト設定の変更履歴・拡張 SQL の外部 DB 接続・サイト名の解決・API ラッパー・ApiVersion の解説と、関連する改修・設計メモを追加