Help us understand the problem. What is going on with this article?

初心者がWeb APIについて学習する記事

Web API初心者による学習ノートです。

参考資料

Web とは?

Webの用途

Webサイト:情報の閲覧
ユーザインターフェースとしてのWeb:デバイスの設定画面やHTMLヘルプなど
プログラム用APIとしてのWeb ( Web API ):プログラム向けのインターフェース

基本的な用語

  • HTTP(Hypertext Transfer Protocol)
    • 通信のためのルール(プロトコル)
  • URI(Uniform Resource Identifier)
    • リソース識別子
    • URL は URI に含有され、「位置」を示している
  • HTML(Hypertext Markdown Language)

    • Web で表示するための文書フォーマット
  • 分散システム

    • 複数のサーバーがシステムを動かす。
    • 現在は大体こっちが使われている。
  • 集中システム

    • つよつよサーバー(メインフレーム)がシステムを動かす。

REST とは?

REST とはWebのアーキテクチャスタイルである

「アーキテクチャスタイル」とはなんぞや?

  • アーキテクチャスタイルとは、具体的なアーキテクチャを設計する際の指針、作法、流儀のこと。
  • 「この技術を使おう!」とか「こういうサーバ構成にしよう!」といった具体的な概念ではない。
用語 抽象度 具体例
アーキテクチャスタイル REST
アーキテクチャ サーバー、ブラウザ etc.
実装 Apache、Chrome etc.

RESTにおける「リソース」を理解する

「リソース」とは、Web上に存在する、名前を持った様々な情報である。

リソースの例

  • 横浜の天気予報
  • 今読んでるQiita記事
  • 子猫のフリー画像

「リソースの名前」ってなんだ?

  • 「リソースの名前」=「URI」
  • 世界中にとんでもない数存在しているリソース達は、それぞれURIで一意の名前を持っている。
  • URIを使うと、プログラムはリソースが表現する情報にアクセスできる。
  • 1つのリソースが複数のURIを持つこともある。

リソースの名前の例

RESTを構成する6つのアーキテクチャスタイル

  • RESTは下記の表の6つのアーキテクチャスタイルを組み合わせたアーキテクチャスタイルである。
  • いくつかのスタイルを除外しても良い。
アーキテクチャスタイル 概要
クライアント/サーバ UIと処理を分離する
ステートレスサーバ クライアントのアプリケーション状態をサーバが管理しない
キャッシュ サーバから取得したリソースを再利用し、クライアントとサーバの通信回数を減らす
統一インターフェース リソースに対する操作を、統一した限定的なインターフェースで行う
階層化システム システムをいくつかの階層に分離する
コードオンデマンド プログラムコードをサーバからDLし、クライアント側で実行する

URIの基本

URIの構文

URIの例
http://user:pass@site.example.com:8000/article?id=99&category=diary#about
対応箇所 役割 概要
http URIスキーム 通信プロトコルを表す(大体httpかhttps)
user:pass ユーザ情報 「<ユーザ名>:<パスワード>」の形式
site.example.com ホスト名 ドメイン名またはIPアドレス
8000 ポート番号 ホストにアクセスするときのプロトコルで用いるTCPポート番号
/article パス 階層を表し、一意なリソースを指している
id=99&category=diary クエリパラメータ 検索する際などに、追加情報を「<名前>=<値>」の形式で記述する
#about URIフラグメント リソース内部の更に細かい部分を特定するときに使う

絶対URIと相対URI

URIのパスは、OSのファイルシステムと同じような階層構造を持っている。

URIの種類 概要
絶対URI http://example.com/hoge/piyo OSファイルシステムで言うところの「絶対パス」
相対URI /hoge/piyo OSファイルシステムで言うところの「相対パス」
ベースURI http://example.com/ 相対URIの起点を指定するURI

URIで使える文字

URIでは下記の文字が使える。

  • アルファベットA-Z,a-z
  • 数字0-9
  • 記号-.~:@!$&'()

また、日本語など上記の文字列以外をURIに入れる際は「%エンコーディング」でその文字をエンコードする必要がある。

クールなURI設計

What makes a cool URI?
A cool URI is one which does not change.
What sorts of URI change?
URIs don't change: people change them.
(引用:https://www.w3.org/Provider/Style/URI.html)

クールなURIとは?
クールなURIとは変わらないもののこと。
どんなURIが変わってしまう?
URIは変わらない:人がそれを変更するのだ。
(引用:https://www.kanzaki.com/docs/Style/URI.html)

上記からもわかるように、最強のURIとは「変わらないURI」である。

変わらないURIを設計するための四か条

其の一:プログラミング言語に依存した拡張子やパスを含めない

悪い例
http://sample.com/cgi-bin/login.pl
http://sample.com/servlet/LoginServlet

特定言語などに依存した表記をしていると、将来的に言語を変更した際にURIも変えなければならない。

其の二:メソッド名やセッションIDを含めない

悪い例
http://sample.com/Login.do?action=showLoginPage
http://sample.com/main.jsp?sessionid=9999

メソッドやセッションIDが変わるとURIも変わってしまう。

其の三:URIには「リソースを指し示す名詞」を使う

悪い例
http://sample.com/user/show/999

動詞はHTTPメソッドで表現できるため、URIには名詞を用いる。

其の四:できるだけシンプルかつ人間が理解できるものにする

悪い例
http://sample.com/posts/category/hobby/camera/999

URIはシンプルイズベストである。

URIの変更方法

  • どうしてもURIを変更したい場合は、できるだけリダイレクト(=古いURIを新しいURIに転送するHTTPの仕組み)を行う。
  • ページランクを引き継げるため、SEO的にもGOOD。
Redirectの種類 概要
301 Redirect 恒久的なURIの変更
302 Redirect 一時的なURIの変更

URI設計のテクニック

バージョン番号を含める

有名サイトAPIのURI例
Twitter API | https://api.twitter.com/1.1/
Qiita API | https://qiita.com/api/v2/

将来的なAPI刷新時にバージョン番号を変更すれば良く、修正しやすい。

拡張子でリソースの表現を分ける

拡張子で言語を指定する例
【日本語】http://sample.com/2020/01/01/press.ja
【英語】http://sample.com/2020/01/01/press.en
拡張子でフォーマットを指定する例
http://sample.com/sampledata/item.txt
http://sample.com/sampledata/item.json

1つのリソースが複数の表現を持つ場合、拡張子で各表現を分ける手法がある。

URIの不透明性を保つ

URIが不透明である状態とは?

  • URIからリソースの構造が推測できない
  • クライアント側でURIを構築しない

URIが不透明でないと・・・

  • URIに拡張子を含めると、その言語で操作される可能性
  • API経由以外でサーバから情報を抜き出される可能性

HTTPの基本

TCP/IPの4階層モデル

HTTPは「TCP/IP」というネットワークプロトコルをベースとしているため、まずはこちらを理解する。

階層 対応するもの 説明
アプリケーション層 HTTP アプリケーション毎の通信プロトコルを決定する層
トランスポート層 TCP データ転送の抜け漏れをチェックする層
インターネット層 IP データを送るための層
ネットワークインターフェース層 Ethernet LANケーブルなどの物理的な層

HTTPの歴史

HTTPは進化しており、割と最近になってからHTTP2.0が使われ始めた

バージョン 公開年 特徴
HTTP 0.9 1991年 GETメソッドのみ
HTTP 1.0 1996年 ステータスコードなどのレスポンスヘッダの追加
POSTメソッドなどの追加
HTTP 1.1 1999年 原則、1通信=1リクエスト=1レスポンス
HTTP 2.0 2015年 ストリームの多重化による複数リクエストの同時通信

リクエストとレスポンスの流れ

下記にWebページを表示する際のリクエストとレスポンスの流れを示す。

クライアント側 サーバ側
1 リクエストMSGの構築 待機
2 リクエストMSGの送信 待機
3 待機 リクエストMSGの受信
4 待機 リクエストMSGの解析
5 待機 HTMLを取得
6 待機 レスポンスMSGの構築
7 待機 レスポンスMSGの送信
8 レスポンスMSGの受信 待機
9 レスポンスMSGの解析 待機
10 レンダリング等の処理 待機

HTTPメッセージ

  • 前項でクライアントとサーバ間を飛び交っていたリクエストメッセージレスポンスメッセージを、まとめてHTTPメッセージと呼ぶ。
  • HTTPメッセージは下記の3つの要素で構成されている
    1. スタートライン
      • リクエストの場合は「リクエストライン
      • レスポンスの場合は「ステータスライン
    2. ヘッダ
    3. ボディ

下記にリクエストとレスポンスそれぞれの構造を示す。

リクエスト レスポンス
リクエストライン /
ステータスライン
メソッド:(例) GET
パス:(例) /post/999
プロトコルバージョン:(例) HTTP/2
プロトコルバージョン:(例) HTTP/2
ステータスコード:(例) 200
テキストフレーズ:(例) OK
ヘッダ
(メタデータ)
accept:要求するデータ形式
Host:リクエスト先のホスト名
User-Agent:リクエスト元情報
content-type:返ってくるデータ形式
ボディ
(実データ)
・POSTやPUTの際に使う
・作成するリソース情報等
・サーバが返す実データ
・HTML, JSON etc.

HTTPメッセージの中身をみてみる
1. このページでAPIをいろいろ叩く
2. Chrome開発者ツールやTalend API Tester等でリクエストとレスポンスの中身を見てみよう

httpbin.orgへのリクエスト例
GET /json HTTP/1.1
Accept: application/json
Host: httpbin.org
httpbin.orgからのレスポンス例
HTTP/1.1 200
access-control-allow-credentials: true
access-control-allow-origin: *
content-length: 429
content-type: application/json
date: Sun, 00 Nov 2020 00:00:00 GMT
server: gunicorn/19.9.0
status: 200

{
  "slideshow": {
    "author": "Yours Truly", 
    "date": "date of publication", 
    "slides": [
      {
        "title": "Wake up to WonderWidgets!", 
        "type": "all"
      }, 
      {
        "items": [
          "Why <em>WonderWidgets</em> are great", 
          "Who <em>buys</em> WonderWidgets"
        ], 
        "title": "Overview", 
        "type": "all"
      }
    ], 
    "title": "Sample Slide Show"
  }
}

HTTPのステートレス性

ステートレス」とは「サーバがクライアントの状態を管理せずに通信する」ことである。
実世界のやり取りを考えるとわかりやすい。

「ステートフル」をスタバで例える
客 「コーヒーをお願いします」
店員「ホットとアイスどちらにしますか?」
客 「ホットで!」
店員「サイズはどれになさいますか?」
客 「トールでお願いします」
店員「サイドメニューはよろしいですか?」
客 「クロワッサン1つください」
店員「以上でよろしいですか?」
客 「はい」
店員「かしこまりました」

ステートフルの特徴
ステートフルなやりとりは簡潔であるが、サーバが常にクライアントのアプリケーション状態を覚えていなければならないため、接続先が多くなると管理しきれない。

「ステートレス」をスタバで例える
客 「コーヒーをお願いします」
店員「ホットとアイスどちらにしますか?」
客 「コーヒーをホットで!」
店員「サイズはどれになさいますか?」
客 「コーヒーをホットで、サイズはトールでお願いします」
店員「サイドメニューはよろしいですか?」
客 「コーヒーをホット、サイズはトールで、サイドメニューにクロワッサン1つください」
店員「以上でよろしいですか?」
客 「コーヒーをホット、サイズはトールで、サイドメニューにクロワッサン1つでお願いします。以上!」
店員「かしこまりました」

ステートレスの特徴
ステートレスなやりとりは冗長ではあるが、サーバがクライアントのアプリケーション状態を覚えなくて良い。
また、通信エラー時は処理が重複する可能性がある。

HTTPメソッド

HTTPメソッドの種類

  • HTTPメソッドは8つ存在するが、主要なものは下表の6つである。
  • 下表に示す4つのメソッドでCRUDを実装することが多い。
メソッド CRUD 役割
GET Read リソースの取得
POST Create 子リソースの作成
リソースへのデータ追加etc.
PUT Update /
Create
リソースの更新
(存在しなければ作成)
DELETE Delete リソースの削除
HEAD - リソースのヘッダ取得
OPTIONS - リソースがサポートしているメソッドの取得

各メソッドのべき等性と安全性

べき等性:ある操作を何回行っても結果が同じこと
安全性:操作対象のリソースの状態を変化させないこと

メソッド べき等性 安全性
GET
POST × ×
PUT ×
DELETE ×
HEAD
OPTIONS

ステータスコード

レスポンスメッセージのステータスラインに記述されたステータスコードを見れば、
レスポンスの大まかな内容を把握することができる。

N百番代ごとの大まかな分類

ステータスコード 意味 詳細
100-199 処理中 ・処理が継続していることを示す
・クライアントがそのままリクエストを継続するか再送信するか等を判定
200-299 成功 リクエストが成功したことを示す
300-399 リダイレクト ・他のリソースへのリダイレクトを示す
・Locationヘッダを見て新しいリソースへ接続
400-499 クライアントエラー クライアントのリクエストが原因でエラーが発生したことを示す
500-599 サーバーエラー サーバー側の原因でエラーが発生したことを示す

よく使うステータスコード(成功系)

ステータスコード テキストフレーズ 意味・特徴
200 OK GET:取得したリソースがメッセージ本文で送信される
HEAD:ヘッダ情報がメッセージ本文で送信される
PUT / POST:操作の結果がメッセージ本文で送信される
201 Created 新たなリソースが作成された
PUTまたはPOSTのレスポンス
204 No Content リクエストのレスポンスとして送信するコンテンツは無いが、
リクエストは成功
301 Moved Permanently リソースの恒久的な移動

よく使うステータスコード(エラー系)

ステータスコード テキストフレーズ 意味・特徴
400 Bad Request リクエストの構文やパラメータが間違っている
403 Forbidden コンテンツへのアクセス権が無い
404 Not Found リソースが存在しない、URLを解釈できない etc.
500 Internal Server Error サーバ側で処理できないエラーが発生
502 Bad Gateway ゲートウェイとなるサーバが正常に動作しない
503 Service Unavailable サーバがメンテナンスや過負荷等でダウンしている

(参考)HTTP レスポンスステータスコード
https://developer.mozilla.org/ja/docs/Web/HTTP/Status

HTTPヘッダ

ヘッダでは、メッセージのボディに対する付加的な情報(メタデータ)を表現する。
ここでは、よく使うヘッダを挙げる。

MINE(Multipurpose Internet Mail Extensions)メディアタイプの指定

  • Content-Typeヘッダでメディアタイプを指定する。
  • charsetパラメータは文字エンコーディングを指定する。
ヘッダ記述例
Content-Type: application/json; charset=utf-8
主要なType 意味 type/subtypeの例
text 人が読んで直接理解できる text/plain
image 画像データ image/jpeg
audio 音声データ audio/mpeg
video 動画データ video/mp4
Application その他のデータ application/json

HTTP認証のためのヘッダ

  • リソースにアクセス制限がかかっている場合、認証が必要。
  • Authorizationヘッダに認証情報を付与する。
ヘッダ記述例
Authorization: Basic TupRWRpQwLgEPVndgC==
認証方法 仕様 特徴
Basic認証 base64でエンコードされた
ユーザIDとパスワードを使用
・簡単にデコードできる
・HTTPSによる通信暗号化が必要
Digest認証 デコードできない
ハッシュ化されたパスワードを使用
・メッセージは暗号化されない
・HTTPSによる通信暗号化が必要
Bearer認証 権限付きのトークンを取得して使用する OAuth2.0で保護されたリソースなどの認証に使う

キャッシュ

  • キャッシュ=リソースを再利用する仕組み
  • Cache-Controlヘッダを使い、検証と再取得の条件を設定する
指定方法 目的
Cache-Control: no-store キャッシュしない
Cache-Control: no-cache キャッシュするが再検証する
Cache-Control: max-age=86400 相対的な有効期限[秒単位]を設定する
Cache-Control: must-revailidate 必ず検証する
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away