【スケジューラ】NASA Open APIを利用してみる

先ずは[NASAのOpen APIページ](https://api.nasa.gov/)に行き、APIキーを取得しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/b8f2b54a-3dd4-1ccc-d660-24f20bad7fdf.png)

APIキーが取得できたら、今度はどのAPIを利用するかを選びます。
今回は`Browse APIs`ページから**Mars Rover Photos**を選びました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/d284be2f-563f-291e-86bd-cf09e81fbe04.png)
\+ 符号をクリックして、使用説明文を表示させます。エンドポイントのURLといくつかのパラメータの説明があります。
Example Queriesの一番最初の例を使用します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/828718d8-b0cb-7eee-7b3f-25fde3d7b554.png)

## 核となるタスクの作成 ##
Sharperlightスケジューラタスクを使用して、NASAの写真データを取得してみます。
Sharperlightアプリケーションメニューからスケジューラを起動します。
`新規`ボタンで新しいタスクの作成を開始します。
タスクのダイアログが起動したら、**コード**と**グループ**を決定します。
次に`アクション`タブに移動して、実際にタスクに課す仕事を定義します。
ここでは、クエリビルダを使用して先ほど選択したAPIエンドポイントからデータを取得し、あらかじめ準備したローカルのデータベースに保存するといった一連の作業を定義します。

### クエリの組み合わせアクション ###
`アクション`タブの新規アイコンでアクション一覧を表示させ、**クエリの組み合わせ**を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/73849d1d-0c26-2634-99b1-86e648d68bb2.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/75cc0867-39fd-e7c5-2153-f708e8b502da.png)
**クエリの組み合わせ**アクションが追加されると、`クエリを編集`ボタンで先ほど選択したAPIエンドポイントに対するクエリを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/31cb59ba-1b11-ef4a-8134-2c566ece3d8e.png)
起動するクエリビルダでは、
* **モード**：詳細レポート
* **製品**：システム
* **テーブル**：Web ページのテーブル、CSV、JSON、XML またはOData
* **URLリンク**：(Example Queriesの一番最初の例)
```            
https://api.nasa.gov/mars-photos/api/v1/rovers/curiosity/photos?sol=3495&page={@Page}&api_key=あなたが取得したAPIキー
```
パラメータ**sol**の値を`3495`に、更に**page**パラメータを追加しました。
page番号はこのクエリに対する引数として渡すよう設定します。
また、戻ってくるJSON形式のデータのどの位置から解析するかを、**開始位置**フィルターに指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/d30b982a-0b03-1174-b57c-cc7cd2c499f3.png)
**URLリンク**フィルターにURLを記入すると、Sharperlightエンジンが実際にそのURLにアクセスし、戻ってくるデータを解析し、選択可能なフィールド一覧を`選択`領域に表示してくれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/8596cb35-2cf7-ee18-b1d3-26d7f881a51b.png)
ここでは、**camera**列や**rover**列は、更にJSONデータ形式のままなので、拡張表現を利用してそれぞれの値を取り出します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/a1a72c77-d363-dc00-9c18-84df185c6607.png)
この方法で戻ってくるデータをいくつかの列に分解します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/0b3ece88-f9fa-2c64-ba1f-2c539b5fa408.png)
各出力列には名前をつけて、保存する際にその名前で参照できるようにします。属性欄の%のついた文字列がその列の参照名です。%RoverIdや%RoverName
プレビューでクエリの動作確認を行います。
データが返ってきました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/a20d752e-32cb-4531-3e6a-682d8714c6b7.png)
`OK`ボタンでクエリを保存します。

### SQLステートメントアクション ###
次に新規アクションとして**SQLステートメント**アクションを追加します。
先に作成した**クエリの組み合わせ**アクションは、For文のような働きをし、取得したデータを一行ずつその次のアクションに渡し処理させます。
ここでは**SQLステートメント**アクションで一行ずつデータベースに書き込むようにします。
今回は前もってデータベースとテーブルを作成し、そのデータベースに対するSharperlight用のデータモデルを作成しておきました。もちろんクライアントのセットアップでそのデータベースとの接続も完了しています。
よって、**SQLステートメント**アクションでは下図のように、その接続を利用してSQL文を発行することが可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/8326163b-90e7-0376-217b-fd05117d3889.png)
あとは、**クエリの組み合わせ**アクションから渡される値を、データベースに書き込むためのSQL文をこのように定義するだけです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/59e8a8cd-c762-cb3a-fcca-d6d58ad2ce5a.png)
**クエリの組み合わせ**アクションから渡される値は全て`{%xxxxxx}`で参照できます。
```
UPDATE [dbo].[MarsPhoto]
       SET [Rover_Raw]='{%RoverRaw}'
       ,[Rover_Id]={%RoverId}
       ,[Rover_Name]='{%RoverName}'
       ,[Rover_LandingDate]='{%RoverLandingDate}'
       ,[Rover_LaunchDate]='{%RoverLaunchDate}'
       ,[Rover_Status]='{%RoverStatus}'
       ,[Camera_Raw]='{%CameraRaw}'
       ,[Camera_Id]={%CameraId}
       ,[Camera_RoverId]={%CameraRoverId}
       ,[Camera_Name]='{%CameraName}'
       ,[Camera_FullName]='{%CameraFullName}'
       ,[ImageURL]='{%ImageURL}'
       ,[EarthDate]='{%EarthDate}'
WHERE [Id]={%id};
IF @@ROWCOUNT=0
BEGIN
INSERT INTO [dbo].[MarsPhoto]
           ([Id]
           ,[Rover_Raw]
           ,[Rover_Id]
           ,[Rover_Name]
           ,[Rover_LandingDate]
           ,[Rover_LaunchDate]
           ,[Rover_Status]
           ,[Camera_Raw]
           ,[Camera_Id]
           ,[Camera_RoverId]
           ,[Camera_Name]
           ,[Camera_FullName]
           ,[ImageURL] 
           ,[EarthDate])
     VALUES
           ({%id},'{%RoverRaw}',{%RoverId},'{%RoverName}','{%RoverLandingDate}','{%RoverLaunchDate}','{%RoverStatus}'
              ,'{%CameraRaw}',{%CameraId},{%CameraRoverId},'{%CameraName}','{%CameraFullName}','{%ImageURL}','{%EarthDate}')
END
```
これでこのアクションの定義は終了。

### クエリの組み合わせ終了アクション ###
最後に新規アクションとして**クエリの組み合わせ終了**アクションを追加します。
これはFor文を閉じる的な意味合いのアクションで、**クエリの組み合わせ**アクションと必ず対を成す必要があります。

以上で取得および書込みタスクの作成は終了。`OK`で保存します。

## 核となるタスクをページ数分繰り返す親タスクの作成 ##
次に、もう一つタスクを作成して、先に作成したタスクをページ番号毎に繰り返し実行できるようにします。
新規タスクを作成し、**クエリの組み合わせ**アクションを利用して、ページ番号が1から20までを返すクエリを定義します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/73169494-6026-7c15-98d5-64d4e7b0d013.png)
そしてその**クエリの組み合わせ**アクションのForループ内で、先に作成した**核となるタスク**を実行するといった具合です。その際にページ番号を引数として渡します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/67ff9b27-53f5-5849-fe1f-7229ec069e23.png)
最後に**クエリの組み合わせ終了**アクションをお忘れなく。
`OK`で保存します。

## タスクの実行 ##
スケジューラダイアログで、親タスクを選択し、右クリックメニューから**実行**を選択します。
エラー無く実行が終了すると、接続したデータベースの指定したテーブルにはNASA Open APIから取得したデータが保存されているはずです。

## 取得したデータの確認 ##
折角なのでSharperlightでレポートを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/fbe8cc99-23a4-5ca2-e04a-db4acb17fec7.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/362e5696-6750-f50c-95f0-567c47943e83.png)
ブラウザで拝見すると...
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/ca72a7b9-66ae-d6c6-d47a-c32c1bc40e8d.png)
是非、お試しあれ。