ApiVersion の決まり方
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)。
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 と同じです。
| 認証方式 | ApiKey | Compatibility_1_3_12: true | Compatibility_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 は送りません。
{
"Version": 1.0,
"Enabled": true,
"PageSize": 200,
"LimitPerSite": 0,
"Compatibility_1_3_12": true
}この設定で次のスクリプトを実行すると、ApiVersion: '1.1' は無視され、レスポンスは 1.0 形式(ClassA などの個別プロパティ)になります。
$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": false | ApiKey なしのリクエストでも ApiVersion が効くようになる。ApiVersion を 1.0 と書いているスクリプトがあれば、その指定どおり 1.0 形式で返るようになる |
| 既定のバージョンを上げる | "Version": 1.1 | ApiVersion を省略しているすべての API(外部の連携を含む)のレスポンスが 1.1 形式になる |
| ApiKey を付けて送る | data に ApiKey を入れる | 画面のスクリプトに API キーを埋め込むことになるので勧められない |
TIP
どれも選べないときは、スクリプト側で 1.0 形式のレスポンスをそのまま扱うしかありません。Compatibility_1_3_12 の条件を外す本体改修の検討は ApiKey なしでも ApiVersion を反映する改修 を参照してください。