レコード一括出力APIについて質問です。 画面表示時に「レコード一括出力依頼の作成」を実行し、その後、画面上の実行ボタンを押下して「レコード一括出力依頼を取得」を実行し、ダウンロード用のURLを取得する仕組みを開発しております。 この時、「レコード一括出力依頼を取得」の実行結果に含まれるstatusが"waiting"となってしまい、期待通りの動作を確認することができません。 実行ボタンではなく、画面表示時に「レコード一括出力依頼の作成」と「レコード一括出力依頼を取得」を連続で実行した場合も同様の結果となりました。 ただし、SPIRAL上ではなく、GoogleのTalend API Testerで実行した場合はstatusが"succeeded"となり、ダウンロード用のURLが取得できております。 APIの記述は、下記のサンプルコードを参考にしております。 https://knowledge.spirers.jp/article/development/detail/6117 上記について、解決策がありましたらご教示いただけますと幸いです。
<?php
//------------------------------
// 設定値
//------------------------------
define("API_URL", "https://api.spiral-platform.com/v1");
define("API_KEY", "xxx");
define("APP_ROLE", "");
define("DB_ID", "xxx");
define("APP_ID", "xxx");
//------------------------------
// レコード一括出力依頼の作成
//------------------------------
$commonBase = CommonBase::getInstance();
// 出力依頼するファイルの設定
$body = array(
// "fileName" => "ファイル名",
"fileFormat" => "csv",
"characterCode" => "utf-8WithBOM",
"hasHeader" => "true",
"headerType" => "displayName",
// "sort" => "データ行ソート",
// "where" => "レコード抽出条件",
"fields" => array(
array("field" => "_id"),
array("field" => "_createdAt"),
array("field" => "_updatedAt"),
array("field" => 1),
array("field" => 2),
array("field" => 3)
)
);
$apiResponse1 = $commonBase->apiCurlAction("POST", "/apps/". APP_ID. "/dbs/". DB_ID. "/records/exports", $body);
$SPIRAL->setTHValue("API_RESPONSE", $apiResponse1);
//------------------------------
// レコード一括出力依頼の取得
//------------------------------
if($SPIRAL->getParams("click")) {
$commonBase = CommonBase::getInstance();
$recordExportId = $apiResponse1['id'];
$apiResponse2 = $commonBase->apiCurlAction("GET", "/apps/". APP_ID. "/dbs/". DB_ID. "/records/exports/". $recordExportId);
$SPIRAL->setTHValue("API_RESPONSE", $apiResponse2);
}//------------------------------
// 共通モジュール
//------------------------------
class CommonBase {
/**
* シングルトンインスタンス
* @var UserManager
*/
protected static $singleton;
public function __construct() {
if (self::$singleton) {
throw new Exception('must be singleton');
}
self::$singleton = $this;
}
/**
* シングルトンインスタンスを返す
* @return UserManager
*/
public static function getInstance() {
if (!self::$singleton) {
return new CommonBase();
} else {
return self::$singleton;
}
} /**
* V2用 API送信ロジック
* @return Result
*/
function apiCurlAction($method, $addUrlPass, $data = null, $multiPart = null, $jsonDecode = null) {
$header = array(
"Authorization:Bearer ". API_KEY,
"X-Spiral-Api-Version: 1.1",
);
if($multiPart) {
$header = array_merge($header, array($multiPart));
} else {
$header = array_merge($header, array("Content-Type:application/json"));
}
if(APP_ROLE){
$header = array_merge($header, array("X-Spiral-App-Role: ".APP_ROLE));
}
// curl
$curl = curl_init();
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_URL, API_URL. $addUrlPass);
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
if ($method == "POST") {
if ($multiPart) {
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
} else {
curl_setopt($curl, CURLOPT_POSTFIELDS , json_encode($data));
}
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
}
if ($method == "PATCH") {
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
}
if ($method == "DELETE") {
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
}
$response = curl_exec($curl);
if (curl_errno($curl)) echo curl_error($curl);
curl_close($curl);
if($jsonDecode){
return $response;
}else{
return json_decode($response, true);
}
}
}
?>コメント
■対処方法案2 1)ダウンロードページ:出力依頼時に、非同期でwhereを指定して別ページにリクエスト 2)別ページ:リクエストを受けたページで、「レコード一括出力依頼を作成」のAPIを実行し、依頼成功のレスポンス 3)ダウンロードページ:レスポンスを受けたページで一定時間ごとに別ページに非同期通信を実行し、 「レコード一括出力依頼を取得」のAPIでステータスを確認(失敗時は繰り返し) 4)別ページ:ステータス確認し、「succeeded」の場合に受け取ったファイルURLを、ダウンロードページにレスポンス 5)ダウンロードページ:受け取ったファイルURLを設定したダウンロードボタンを表示 ※注意事項 レコード一括出力が成功になるまで、非同期処理で確認する必要があるため、 設定時間によってはAPIの処理が増えます。 負荷状況によっては遅延が発生する可能性があります。 また、「レコード一括出力依頼を作成」依頼後の離脱や複数人での依頼など、非機能面を考慮いただきますようお願いします。 注意事項を踏まえて、対応についてご検討いただけますでしょうか。
ご回答いただきありがとうございます。 URLの取得について、対処方法案1を参考に解決することができました。 続けて、初歩的な質問となりますが、ダウンロードの手順についてお伺いしたいです。 APIで取得したURLをThymeleafでbodyに渡し、aタグにURLを埋め込んでダウンロードを試みたところ、アクセストークンが必要という旨のエラーが返されました。恐らく、Authorizationヘッダの設定が必要であると認識しておりますが、設定方法が分かっておりません。 APIの共通モジュールの "Authorization:Bearer ". API_KEY とは別に設定が必要なのでしょうか?
ご確認いただきましてありがとうございます。 CSVのダウンロードについてご案内します。 ■CSVダウンロードの仕組みについて レコード一括出力依頼のstatusが「succeeded」となった後に取得できるダウンロード用URLは、APIキーによる認証が必要なエンドポイントとなっております。 そのため、このURLをそのままThymeleafでHTMLのaタグに埋め込んでフロント側から直接ダウンロードを行うことはできません。 (※APIキーがフロントに露出してしまうため、セキュリティ上の問題が生じます) ■対応方法(サーバーサイドでのダウンロード処理) 以下のように、PHP側で該当URLからCSVデータを取得し、フロントにデータとして渡す方法を推奨いたします。 ※後述のPHPをご参照ください。 このようにして取得した$fileDataには、CSVファイルの中身(文字列)が格納されます。 ■フロントへの渡し方 サーバー側で取得したCSVの中身を、Thymeleafを通じてJSへ渡し、JavaScriptでBlob化してダウンロードさせるように実装できます。 ■注意点 以下の手順: 4)別ページ:ステータス確認し、「succeeded」の場合に受け取ったファイルURLを、ダウンロードページにレスポンス 5)ダウンロードページ:受け取ったファイルURLを設定したダウンロードボタンを表示 こちらのフローについては、実際には一度PHP側でCSVデータを取得したうえで、ファイルの中身をダウンロードページに渡す必要があります。 ■別案:DLリンク生成方式(ログ用途) 別の方法として「DLリクエストごとに一時テーブルにログをインサートし、サーバー側で生成した一時DLリンクを表示する」という方法もございます。 ※ただし、この方式はDLボタンの連打などによりファイル容量やDBレコードが圧迫される懸念があるため、運用面での考慮が必要となります。 ※PHPの実行時間には制限がございますので、併せてご注意ください。 ご参考になれば幸いです。 引き続きご不明点があれば、お気軽にご質問ください。
$url = '<<APIレスポンスで取得したダウンロード用URL>>';
$fileData = simpleApiGetWithApiKey($url);
function simpleApiGetWithApiKey($url) {
$header = array(
"Authorization:Bearer " . API_KEY
);
$curl = curl_init();
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($curl, CURLOPT_ENCODING, '');
$response = curl_exec($curl);
if (curl_errno($curl)) {
$response = curl_error($curl);
}
curl_close($curl);
return mb_convert_encoding($response, 'UTF-8', 'auto');
}
ナレッジ
向上チーム
※入力できる文字数の都合上、2つに分けて回答いたします 恐れ入りますが、statusが「succeeded」になる前に出力依頼を取得するAPIを実行しても、ダウンロード用のURLを取得することができません。 出力依頼のstatusが「succeeded」になるまで待つ必要がございますが、そこまでに時間がかかっている可能性がございます。 スパイラル内でPHPを実行している場合は、タイムアウトしていないかご確認ください。 PHP実行アクションでの実行の場合は、通知メールの設定を変更することで、エラー発生時等の通知を受け取ることができます。 ▼通知メール設定 https://support.spiral-platform.com/function/function-user-setting/4181.html また、実行に時間がかかっている場合には、処理を分けて実行することをご検討いただけますと幸いです。 ■対処方法案1 1)「レコード一括出力依頼を作成」APIで依頼を作成して「一括出力依頼ID」を受け取る 2)「レコード一括出力依頼一覧を取得」APIで1)の「一括出力依頼ID」のステータスを確認して、「レコード一括出力依頼を取得」APIを実行する
-
いいね
2025年4月16日(水)