RESTfulなAPI。それは魔法です。

  • 18 December 2021
Post image

 では最後の工程。何かWebAPIを作ってみる。前回の記事では、pythonでWebAPIのリクエストとレスポンスを作ったけど、今回は一般的なWebAPIの構造をやってみる。

究極魔法「RESTful」

 何年か前からWebAPIは、***RESTful(REST)***という構造で作成されることが多くなった。誰でも知っている知識だからこれは絶対に抑えておきたい。後で詳細は"Rest api"とかでググってほしいんだけど、ざっくりの理解でいうと、以下の性質をもつ設計だ。

  1. HTTP経由
  2. 統一されたインターフェースや一意のエンドポイント
  3. ステートレスなクライアントサーバー通信

 うん、こんな要件は一旦どうでもいいわ。一旦以下がRestだと覚えておいて大丈夫。

  1. HTTP通信で、JSONやXMLでデータをやり取りする
  2. GET, POST PUT, PATCH, DELETEなどのHTTPメソッドで通信する
  3. URLの文字列でやりたいことがわかる

JSON形式

 最近は主にJSONでデータをやり取りするのが一般的だ。JSONは以下のような形式のデータをいう。

{
  "name": "太郎",
  "age": 30
}

 なぜ、こんなJSONという形式でAPI通信するのかというと、データ構造を表現したいからなんだよね。この記事で書いたように、やり取りするデータはリクエストボディやレスポンボディに含めてやり取りされる。この**“ボディ"ってのは一般的に1次元**なんだよね。例えば「ユーザー情報」をレスポンスする場合を考えてみよう。
 あるユーザーの「名前」「メールアドレス」「年齢」を返すWebAPIが存在する場合、どのようにデータを構成する? 無理やり文字列で考えた場合。

太郎[email protected]
# "名前""メールアドレス""年齢"

 こんな文字列データを返して、受け取ったクライアントで以下のように分割したらいいじゃん?

太郎, [email protected], 30
# 初めの2文字、3文字目から15文字目まで, 最後の2文字で区切ると正しいデータを取得できる!?

 これ難しいのはわかるよね?まず、名前が2文字って当然決まってないよね。五右衛門三郎さんとはオーバーしまくるよね。また、名前をアルファベットで入力するJohnさんの場合、メールアドレスとの区切りが全くわからない。そこで大昔の人は以下のような構造規約を作っていたらしい。(文字コードなどは無視してね)

太郎[email protected]
# 名前は最大8文字で左つめ0埋め
# メールアドレスは最大255文字左つめ0埋め
# 年齢は最大3文字右つめ0埋め

 これならうまくできそう。むかーしのエンジニアの先輩に聞くとこのようなやり取りをしていたらしいんだよね。しかしこれでは少し不便だ。だってプロジェクトごと、企業ごと、人ごとによってルールは様々。そこで、このようにデータ構造を表すための標準ルールを規定したデータ構造としてJSON形式というものがあるわけだ。JSONはデータ構造の表し方、書き方は全世界共通だ。さらにデータ構造をネスト(入れ子)できるという点でより優れている

{
  "name": "太郎",
  "age": 30,
  "payment": {
    "card": "visa",
    "number": "1111222233334444"
  }
}
// カード情報のデータ構造を入れ子にできる

 んでJSONでやり取りするってのは、このJSON形式でリクエストやレスポンスをするってこと。


HTTPメソッドとエンドポイント

 これは簡単。HTTP通信の種類のこと。種類っていっても勝手に種類名を付けてそのメソッド情報をリクエストヘッダーに付与して送信しているだけ。実際にChromeで確認するとわかる。

 WEBページを開いて見ているのは、ほとんどの場合「GET」メソッドだ。というか今この記事を開いているのは、あなたがブラウザでGETメソッドによりリクエストしたから見られているってこと。
 そして誰かエラい人が「REST APIのルールはこうしようだホイ!」とルールを決めた(もちろんこのルール以外のルールを使用してもRESTfulだが)。ユーザーデータについてのデータのやり取りの場合の例は以下だ。

エンドポイント例 メソッド 意味合い
https://xxx/user GET ユーザー一覧情報取得
https://xxx/user/1 GET ID:1のユーザー情報1件取得
https://xxx/user/ POST ユーザーの新規登録
https://xxx/user/1 PUT ID:1のユーザー情報編集
https://xxx/user/1 DELETE ID:1のユーザーの削除

 urlは「/user」を付けることで、ユーザーデータに対する処理ってことがわかるし、HTTPメソッドにより、ユーザーデータに対してどんな処理をしようとしているのかがはっきりわかる。また、「/user/1」のように/userの後ろには数字が出てくるってルールにしておけば、これを見ただけで『userデータのidが1に対してってことだホイ!』とすぐにわかる規約になる。世の中のほとんどのRestAPIの設計はこのようになっているはずだ。当然PATCHメソッドやOPTIONメソッドなどもほかのメソッドも存在するので、詳細はググってほしい。


やだ。RestAPIってかっこいい

 つまり、RestAPIってURLやHTTPメソッドで目的を表現できるし、JSONとかの便利なデータ構造でやり取りできるし、めちゃくちゃ便利ね。そう。たしかに2021年現在でもRestfulはスタンダードとなっている。他にも説明しないけどRestfulであることで便利なことがたくさんある。なので今回はこの一般的なRestAPI構成で以下作ってみる。
 ちなみに近年ではRest以外のアーキテクチャが使われることも増えてきた。特にgRPCというGoogleが開発したプロトコルは人気だ。つまり、RESTにも弱点というか不満点も多少あるってこと。ただ、超基本であるRestをやってから他のプロトコルにチャレンジしたほうが良いと思うぜ。なぜならそのほうが、「gRPCの良さ」などがはっきりわかるからだ。


API作るのめんどくなってきた

 3回前の記事からここまで長々長々と書いてきたけど、つまり"RestAPI"を作成すればいいってこととその理由を書いてきた。ところで中身の処理は何作るの?って話。やっぱ「目的」がないと何かを作る気が起きないよね。しかもここまでの記事を理解してもらうとわかると思うけど、あとはググったら出来ちゃうからね。前回の続きで、python, Flaskでユーザー編集APIの一部を作ってみる。タスクを分解すると。(誰でもできる考え方参照)
【タスク一覧】

  • flaskでHTTPメソッドを扱う
  • flaskで/user/1の"1”(URLパラメータ)を取得する
  • flaskでjsonによりリクエスト・レスポンス
  • flaskでDB接続、ユーザー情報保存(今回はやらない)

「flask api HTTPメソッド」でググる

 一番上に出てきた記事を参考に。これでPUTメソッドによるリクエストを受け付けるようになる。

from flask import Flask
app = Flask(__name__)

@app.route('/user', methods=['PUT'])
def hello_world():
  return "Hello, World!"

 やばい。眠くなってきた。


「flask api URLパラメータ」でググる

 一番上に出てきた記事を参考に。これでユーザーidを取得できる。

from flask import Flask
app = Flask(__name__)

@app.route('/user/<user_id>', methods=['PUT'])
def hello_world(user_id):
  print(user_id)
  return "Hello, World!"
# 1

 つまんねー。


「flask json リクエスト」でググる

 一番上に出てきた記事を参考に。これでリクエストボディのJSONデータを取得できる。

from flask import Flask
app = Flask(__name__)

@app.route('/user/<user_id>', methods=['PUT'])
def hello_world(user_id):
  data = request.json
  return "Hello, World!"

「flask json レスポンス」でググる

 一番上に出てきた記事を参考に。これでレスポンスをJSONデータで返却できる。今回はリクエストのJSONをそのままレスポンスしてみる。

from flask import *
app = Flask(__name__)

@app.route('/user/<user_id>', methods=['PUT'])
def hello_world(user_id):
  data = request.json
  return jsonify(data)

 ググってコピペするだけの簡単なお仕事です。


データの保存処理など

 あとは以下の箇所にDBへの接続やデータの取得・保存などの処理を書くだけだ。今回はデータベースなどを用意するのがめんどくさいのでやらないけど、同じようにまたググってコピペ(通称ググペ)すれば簡単にできちゃうわけ。

from flask import *
app = Flask(__name__)

@app.route('/user/<user_id>', methods=['PUT'])
def hello_world(user_id):
  data = request.json

  # DBからユーザー情報を取得したり保存したりする処理をここに書く

  return jsonify(data)

もうWebAPIこれでいいでしょ!こんなもん魔法でも何でもないわ!

 ただググってコピペ(通称ググぺ)するだけのことを書くのってこんなにつまらなくて辛いことだったんだね。わたくし知りませんでした。今回作ったWebAPIをサーバー上に配置して、Nginxなどで待ち受けたら実際のサーバーで動くWebAPIが完成する。(これはまた後日書く)
 今回はPythonでやってみたけど、どのプログラミング言語、どのフレームワークを使おうとも同じようにググペで完成する。まぁそのためには、全体のイメージを持っておくことが前提だってこのサイトでは口酸っぱく書いているわけだが。今までもひたすら書いてきたけど、プログラムコードをカタカタかくことなんかよりイメージを持っているかどうかの方が圧倒的に大切だってことが分かってもらえたと思う。
 このWEBAPIのコードをサーバーで起動して待ち受けておけば、例えばWEBブラウザから、例えばスマホアプリから、例えばデスクトップアプリからHTTP通信でデータをやり取りできるってこと。おめでとう。これで君はもうすでに魔法使いだね。

You May Also Like

特定の箇所を自分でいじって。それがWebAPI開発上達の基本

特定の箇所を自分でいじって。それがWebAPI開発上達の基本

 WebAPIを理解する上で、前回の記事と前々回の記事で、通信、サーバー、Webサーバーなどの話を書いてきた。今回は最深部であるアプリケーションの話。 アプリケーションというと、スマホの「アプリ」を思い浮かべてしまう人もいるかもしれないけど、広い意味で「ある特定の機能や目的のために …

Webサーバーが出来上がるまで

Webサーバーが出来上がるまで

 今回からはWebAPIを作ってみようと思う。このサイトのコンセプトに沿って、作成するためのサンプルコードを上げるのではなく思考のプロセスを中心に書いていく。完全な初心者、または、なかなか上達出来ずに悩んでいるエンジニア向けの記事なのであしからず。 前回の記事でネットワークについて …