REST API (Representational State Transfer API) とは
REST API (Representational State Transfer API) とは、以下の6つの REST アーキテクチャの制約に準拠する API のことです。
- Client-Server (クライアントとサーバーの分離)
- Stateless (ステートレス性)
- Cache (キャッシュ可能性)
- Uniform Interface (統一されたインターフェース)
- Layered System (階層化されたシステム・アーキテクチャー)
- Code-On-Demand (コードオンデマンド) [オプション]
引用元が O'Reilly であるものや、企業のドキュメントを重視しました。
https://en.wikipedia.org/wiki/Representational_state_transfer
https://www.redhat.com/ja/topics/api/what-is-a-rest-api
https://www.ibm.com/jp-ja/cloud/learn/rest-apis
https://docs.oracle.com/cd/E28613_01/web.1211/b65960/overview.htm
上の説明だけ読んでもよくわからないと思うので、実例を見ていきましょう。
HTTP ベースの REST API の例でわかりやすく説明
HTTP ベースの REST API では、次の2つの条件を満たす必要があります。(正確にはこちら)
- URI ベースのエンドポイントで「リソース」を決める (
https://api.twitter.com/
) - HTTP メソッドで、リソースの「操作」を決める (GET, POST, PUT, DELETE)
この条件により、REST アーキテクチャの6つの制約を満たします。
REST アーキテクチャの制約 | HTTP ベースの REST API が持つ性質 |
---|---|
Client-Server (クライアントとサーバーの分離) | HTTP プロトコルはサーバークライアントモデル |
Stateless (ステートレス性) | HTTP プロトコルはステートレス |
Cache (キャッシュ可能性) | HTTP ヘッダーでキャッシュの指定可能 |
Uniform Interface (統一されたインターフェース) | ※1 URI を利用してリソースを識別 ※1 HTTP メソッドを利用してリソースの操作を表現 |
Layered System (階層化されたシステム・アーキテクチャー) | HTTP プロトコルは階層化可能。以下例 ロードバランサー > Web サーバー > AP サーバー |
Code-On-Demand (コードオンデマンド) [オプション] | オプション |
※1
Identification of resources - You use the URI (IRI) standard to identify a resource. In this case, a resource is a web document.
Manipulation of resources through these representations - You use the HTTP standard to describe communication. So for example GET means that you want to retrieve data about the URI-identified resource. You can describe an operation with an HTTP method and a URI.
https://stackoverflow.com/questions/25172600/rest-what-exactly-is-meant-by-uniform-interface
例:Twitter の REST API の仕様
Twitter 社が公開している REST API を例として、HTTP ベースの REST API の2つの条件をどのように満たしているか確認します。
- URI ベースのエンドポイントで「リソース」を決める (
https://api.twitter.com/
) - HTTP メソッドで、リソースの「操作」を決める (GET, POST, PUT, DELETE)
URI ベースのエンドポイントで「リソース」を決める
次のように「URI ベースのエンドポイント」と「リソース」が対応しています。
Twitter の URI ベースのエンドポイント | 対応するリソース |
---|---|
https://api.twitter.com /2/tweets/:id | ツイート |
https://api.twitter.com /2/users/:id/following | フォローしているユーザー |
https://api.twitter.com /2/users/:id/likes | お気に入り(ふぁぼ)したツイート |
HTTP メソッドで、リソースの「操作」を決める
REST API では次のように、「HTTP メソッド (操作)」と「URI (リソース)」を組み合わせることで、リソースを操作します。
HTTP メソッド | HTTP メソッドの操作内容 | HTTP メソッドと URI エンドポイントの組 |
---|---|---|
GET | リソースを取得 | GET https://api.twitter.com /2/tweets/:idツイートの取得 |
POST | リソースを追加 (冪等性無し) | POST https://api.twitter.com /2/tweetsツイートの投稿 |
PUT | リソースの作成 or 置き換え (冪等性あり) | ツイートは置き換え (上書き) できない = 該当する Twitter の API は無い |
DELETE | リソースを削除 | DELETE https://api.twitter.com /2/tweets/:idツイートを削除 |
REST API のサンプル
ここでは、Python + Flask を利用して実際に REST API サーバーを作成します。
Flask は Web アプリケーションフレームワークです。Flask の詳細については以下の記事をご覧ください。
また、より実践的な REST API の設計・実装する場合は以下の書籍をご覧ください。
RESTFulなアーキテクチャの概念や実際に Web サービスを設計する方法
Web APIの設計、開発、運用について
作成する REST API の設計
ここでは、以下のような Twitter のツイート機能を持つ REST API を作成します。
REST API | REST API の機能 |
---|---|
GET /tweet | ツイートを取得 |
POST /tweet | ツイートを投稿 |
PUT /tweet/:id | 指定した ID のツイートを更新 |
DELETE /tweet/:id | 指定した ID のツイートを削除 |
REST API サーバーを作成
Python + Flask を利用して REST API サーバーを作成します。
なお、リソースの保存先には SQLite を利用しています。SQLite の詳細は以下の記事をご覧ください。
from flask import Flask, g, request import sqlite3 import json dbpath = 'test.db' #テーブルを保存するファイル app = Flask(__name__) def get_db():#データベースのコネクションを取得 db = getattr(g, '_database', None) if db is None: db = g._database = sqlite3.connect(dbpath) db.execute('CREATE TABLE IF NOT EXISTS tweets_tbl(id INTEGER PRIMARY KEY AUTOINCREMENT, tweet VARCHAR(140))') return db @app.route('/tweet', methods=['GET']) def get_tweet(): con = get_db() #コネクションを取得 con.row_factory = sqlite3.Row #カラム名取得のため cur = con.cursor() #カーソル取得 cur.execute('SELECT * FROM tweets_tbl') tweets = [] for row in cur.fetchall(): #sqlite3.Row オブジェクトを dict に変換 tweets.append(dict(row)) return json.dumps(tweets,indent=2) @app.route('/tweet', methods=['POST']) def post_tweet(): con = get_db() #コネクション cur = con.cursor() #カーソルインスタンスを作成 tweet = request.json["tweet"] #POSTメソッド のデータを取得 cur.execute(f"INSERT INTO tweets_tbl(tweet) values('{tweet}')") #ツイート文をテーブルにINSERT con.commit() return 'Success a Tweet!\n' @app.route('/tweet/<id>', methods=['PUT']) def put_tweet(id): con = get_db() #コネクション cur = con.cursor() #カーソルインスタンスを作成 tweet = request.json["tweet"] cur.execute(f"UPDATE tweets_tbl SET tweet = '{tweet}' WHERE id = {id}") con.commit() return 'Update a Tweet!\n' @app.route('/tweet/<id>', methods=['DELETE']) def delete_tweet(id): con = get_db() #コネクション cur = con.cursor() #カーソルインスタンスを作成 cur.execute(f"DELETE FROM tweets_tbl WHERE id = {id}") con.commit() return 'Delete a Tweet!\n' if __name__ == "__main__": app.run()
REST API クライアントの使い方
今回クライアントとして、以下の2種類を紹介します。
curl をクライアントに利用
ここでは curl を利用して API リクエストを行います。
POST メソッドでツイートを投稿
{
"tweet": "Hello World!"
}'
Success a Tweet!
GET メソッドでツイートを取得
[ { "id": 1, "tweet": "Hello World!" } ]
PUT メソッドでツイートを更新
{
"tweet":"Change World"
}'
Update a Tweet!
[ { "id": 1, "tweet": "Change World" } ]
DELETE メソッドでツイートを削除
Delete a Tweet!
[]
Python の requests をクライアントに利用
ここでは、Python の requests ライブラリを利用して API リクエストを行います。
POST メソッドでツイートを投稿
import requests import json url = 'http://localhost:5000/tweet' headers = {'Content-Type': 'application/json'} data = {"tweet": "Hello World!"} res = requests.post(url, headers=headers ,data=json.dumps(data)) print(res.text)
Success a Tweet!
GET メソッドでツイートを取得
import requests url = 'http://localhost:5000/tweet' res = requests.get(url) print(res.text)
[ { "id": 1, "tweet": "Hello World!" } ]
PUT メソッドでツイートを更新
import requests import json url = 'http://localhost:5000/tweet/1' headers = {'Content-Type': 'application/json'} data = {"tweet": "Change World!"} res = requests.put(url, headers=headers ,data=json.dumps(data)) print(res.text)
Update a Tweet!
[ { "id": 1, "tweet": "Change World!" } ]
DELETE メソッドでツイートを削除
import requests import json url = 'http://localhost:5000/tweet/1' res = requests.delete(url) print(res.text)
Delete a Tweet!
[]
REST API の認可・認証
REST API は OpenID Authentication 2.0 (OAuth 2.0) や OpenID Connect (OIDC) を利用して認可・認証することで、API を叩くユーザーにアクセス制限をします。
OpenID Authentication 2.0 (OAuth 2.0)
アクセストークン (認可情報) により REST API のアクセス権限を制御する場合は、以下の OAuth 2.0 の記事をご覧ください。
OpenID Connect (OIDC)
アクセストークン (認可情報) ・ID トークン (認証情報) により REST API のアクセス権限を制御する場合は、以下の OIDC の記事をご覧ください。
ID フェデレーション
別の認証基盤から ID トークン (認証情報) を受け取る場合は ID フェデレーションの記事をご覧ください。