Couchbase 5.0でリリースされたcURLという名のジャイアニズムでAPIをSELECT文で取得する

Couchbaseで5.0から `cURL`という関数が実装されました。
DBなのに `cURL` が使えてしまうのです。
https://blog.couchbase.com/developer-release-curl-n1ql/

つまりどういうことかというのを Google MapのAPIで説明すると。

```sql
SELECT CURL("https://maps.googleapis.com/maps/api/geocode/json", {"request":"GET", "data":"address=minato&components=country:Japan&key=APIKEY"});
```

というようにCouchbase （データベース）にリクエストすると、
Couchbaseはまるで自分が保持しているかのように、リクエスト結果をリクエスト結果を返します。
（もちろんCouchbaseはGoogle MapのAPIレスポンスを事前に保持してはいません。）

```json
[
  {
    "$1": {
      "results": [
        {
          "address_components": [
            {
              "long_name": "Minato",
              "short_name": "Minato",
              "types": [
                "locality",
                "political"
              ]
            },
            {
              "long_name": "Tokyo",
              "short_name": "Tokyo",
              "types": [
                "administrative_area_level_1",
                "political"
              ]
            },
            {
              "long_name": "Japan",
              "short_name": "JP",
              "types": [
                "country",
                "political"
              ]
            }
          ],
          "formatted_address": "Minato, Tokyo, Japan",
          "geometry": {
            "bounds": {
              "northeast": {
                "lat": 35.6825986,
                "lng": 139.7828356
              },
              "southwest": {
                "lat": 35.6231249,
                "lng": 139.7087511
              }
            },
            "location": {
              "lat": 35.6580681,
              "lng": 139.7515992
            },
            "location_type": "APPROXIMATE",
            "viewport": {
              "northeast": {
                "lat": 35.6825986,
                "lng": 139.7828356
              },
              "southwest": {
                "lat": 35.6231249,
                "lng": 139.7087511
              }
            }
          },
          "place_id": "ChIJ8yIZtLuLGGARrGzw8nX96zM",
          "types": [
            "locality",
            "political"
          ]
        }
      ],
      "status": "OK"
    }
  }
]
```
（ローカル環境で649msかかりました）

これだけだと、普通にcURLを叩いたのと大差ありません。

たとえば、先程のリクエストのうち、必要なものは、 `geometry` だけだったとしたらどうでしょう？
通常のSELECT文同様に扱えるので、FROMを`cURL`のリクエストにしてSELECTで取得したい項目を絞れます。

```sql
SELECT result.geometry FROM CURL("https://maps.googleapis.com/maps/api/geocode/json", {"request":"GET", "data":"address=minato&components=country:Japan&key=APIKEY"}).results[0] AS result;
```

```json
[
  {
    "geometry": {
      "bounds": {
        "northeast": {
          "lat": 35.6825986,
          "lng": 139.7828356
        },
        "southwest": {
          "lat": 35.6231249,
          "lng": 139.7087511
        }
      },
      "location": {
        "lat": 35.6580681,
        "lng": 139.7515992
      },
      "location_type": "APPROXIMATE",
      "viewport": {
        "northeast": {
          "lat": 35.6825986,
          "lng": 139.7828356
        },
        "southwest": {
          "lat": 35.6231249,
          "lng": 139.7087511
        }
      }
    }
  }
]
```
（ローカル環境で167.96msかかりました。）

これは、APIで用意されているフィールドの絞込オプションを使っているわけではなく、Couchbaseのエンジンで、項目の出し分けをしているので、APIで想定していないリクエスト結果の取得もプログラムの実装をせずにクエリを書くだけで対応できてしまいます。

今回はやりませんでしたが、普通のデータを扱うのと同じように使えるので、APIの取得結果とDBの内容を突き合わせたい場合も、プログラムでAPIリクエストしてきたデータとDBから取得してきたデータをプログラム書いて突き合わせるのではなく、自前のデータとcURLで取得したデータをCouchbase上でJOINするだけで可能になりました。


**`おまえのものは俺のもの。俺のものも俺のもの`**

![j1.jpeg](https://qiita-image-store.s3.amazonaws.com/0/9094/1e1512e9-3472-f3dd-d60b-cd68c49dff09.jpeg)

FacebookやTwitterのデータはサービス作るとよく使うので、Couchbaseで取得＆加工してからプログラムに渡すとかという使い方ができそうです。

参照：　https://developer.couchbase.com/documentation/server/current/n1ql/n1ql-language-reference/curl.html


詳しく書きませんでしたが、cURLを使う場合は、セキュリティの観点からリクエスト先をwhitelistに登録する必要があります。
全ノードでこの対応が必要なので、若干厄介です。参照にwhitelistの作り方も書かれてるので参考にしてください
（デプロイする仕組み作って、おなじwhitelistを全サーバに展開するとかしたら楽そう）