このブログは更新を終了しました。移転先はこちらです。

2023-12-10

サイトの作り方②APIを利用してみる

 Noratetsu Houseの作り方の続きです。

 今回はAPIの利用について。

経緯と断り書き

 ここまでの記事はこちら。

 この一連の記事はあくまで「のらてつのサイトはどうやってできているのか」を書いておくものであり、勉強の取っ掛かりになるためにやっているだけなので、正確で十分な知識を提供するものではありません。


 

 APIとは何なのか。「Application Programming Interface」の略で、異なるシステムの間を繋ぐインターフェースで…と言って分かるなら誰も苦労しないでしょう。「APIとは」で検索して出てくるそれらの説明は定義であって、理解を助けてくれるとは限りません。

 実際的なイメージは、特定のURLにアクセスするとそのサービスの中にあるデータを取り出したり編集したりできるもの、という感じです。その行為を俗に「APIを叩く」と言います。

 

 APIを利用できる言語はJavaScriptだけではありませんが、ここではJavaScriptでの使い方に触れます。(それ以外の言語については門外漢のため。)

 JavaScriptでAPIと通信するには、以下のような手段があります。

  • fetch

  • XMLHttpRequest

  • jQuery.ajax

 私はfetchしかまともに使ったことがないので、今回はfetchについて書きます。2015年に導入された比較的新しい技術で、それ以前はXMLHttpRequestかjQuery.ajaxが使われていたということになると思います。いずれも目的はほぼ同じものと思います*1

 fetch(Fetch API)は、APIと通信するほか、「ローカルにあるjsonファイルからデータを持ってきたい」という時にも使用します。まず普通に自分のローカルファイルから中身を取り出すコードを見てみましょう。

 fetch関数はfetch(URL, オプション)の形で使います。ローカルファイルからただデータを取り出す場合はオプションは必要ありません。fetchは非同期処理でありプロミスという形式になっているので、取得したデータはthenで連結して処理していきます(プロミスチェーン)。async/awaitを使って書く方法もあります。

// 同ディレクトリ内のtest.txtファイルの中身の文字列を取得したい
fetch('./test.txt')
.then(response => response.text())
.then(text => {
  // 引数textには「test.txt」の中身の文字列が入っている
  console.log(text);
})
 
// 同ディレクトリ内のdata.jsonファイルの中身のオブジェクトまたは配列を取得したい
fetch('./data.json')
.then(response => response.json())
.then(json => {
  // 引数jsonには「data.json」の中身がオブジェクトまたは配列に変換されて入っている
  console.log(json);
})
 
// async/awaitを使う場合に作る関数の例
async function getData() {
  const response = await fetch('./data.json');
  const data = await response.json();
  console.log(data);
}

 例えばScrapboxなどのWebアプリケーションのデータをjsonファイルとしてダウンロードして、それを自分が使いたいと思った場合は、こうして取り出すことで自分のプログラム内でデータを使うことができます。

 これがわからないうちは「バックアップデータはtxtファイルかcsvファイルにしてほしい」と思ったりするものですが(私はそうでした)、自分でコードを書くようになるとむしろtxtやcsvは扱いが面倒くさくなるので「jsonかSQLiteであってくれよ」と感じるようになると思います(私はそうです)。なおSQLiteはスマホアプリなどでしばしば使われるデータベースの形式で、JSONへの変換が容易です。

 

 APIがただ文字列を提供してくれている場合、APIの通信時も同じ形になります。例としてopenBDのAPIにアクセスしてみましょう。

const ISBN = '978-4004150930'; // 梅棹忠夫著『知的生産の技術』のISBN
fetch('https://api.openbd.jp/v1/get?isbn=' + ISBN)
    .then(res => res.json())
    .then(data => console.log(data))

 コンソールには『知的生産の技術』の書誌情報がオブジェクトの形で表示されていると思います。なおISBNは本のバーコードそばに書いてあるほか、書名で検索すればわかります。

 

 APIは不特定多数に向けて公開してくれているとは限りません。openBDの利用にはログインは要りませんが、基本的にはサービスへのユーザー登録が必要なものの方が多いかと思います。人がコストを投じて作ってくれたデータや機能を使用するものなので、有料であることも多いです(昨今話題のOpenAIもそうです)。ユーザー登録や支払いの設定をしてAPIを使う権利を得るとAPI keyというものをもらえます。

 APIのURLのパラメータにAPI keyを含めてアクセスすることでAPIが利用できるようになっているものをしばしば見かけます。これによってサービス側は「誰がどのAPIをどのくらい利用したか」を把握できるようになっています。

 

 また、例えばDynalistのデータを取得したり編集したりしたいとなれば、当たり前ですが自分のデータにアクセスする権限が必要なので、APIの利用時にはその権限があるかどうかの認証をパスしなければなりません。そのためのパスワードのようなものとしてDynalistのサイトからAPI secret tokenというものを発行してもらいます。

 そうした時に、fetch(URL, オプション)のオプションの部分に認証をパスするための情報を書くことになります。決まった書式があるのでそれに従ってオブジェクトにして引数に入れます。あとは、「どの情報がほしいか」や「どう編集したいか」などを送信する必要がある場合も、このオプション部分に記述します。例えばDynalist APIではこうなります。

const token = 'hoge'; // secret tokenをここに入れる(うっかり公開しないように注意)
const fileId = 'fuga'; // ファイルのURL(https://dynalist.io/d/fuga)のfugaの部分を入れる 
fetch('https://dynalist.io/api/v1/doc/read', {
    method: 'POST',
    body: JSON.stringify({
        token: token,
        'file_id': fileId,
    }),
})
    .then(response => response.json())
    .then(data => {
        console.log(data);
        // dataを使って任意の処理
    })

 この場合、自分のデータにアクセスするための鍵となる「secret token」と、どのファイルにアクセスしたいのかの「file_id」情報を伴って通信することで、目的のデータを受け取ることができるわけです。

 

 Dynalist APIについては次回もう少し詳しく解説します。API利用の概要についてはこんなところです。


*1: XMLHttpRequest、Fetch、$.ajaxは、具体的に何が違うのか