レコード一括出力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を実行する