📖 Reference
-
(JA) HTTP レスポンスステータスコード
-
(JA) HTTP リクエストメソッド
-
(EN) HTTP request methods
サービスをローカルで立ち上げると、ブラウザで http://127.0.0.1:9000
からサービスにアクセスすることができるようになりました。
次に、curlというコマンドを使ってアクセスをしてみます。 curlがインストールされていない場合、インストールしてください。
curl -X GET 'http://127.0.0.1:9000'
ブラウザと同じように{"message": "Hello, world!"}
がコンソール上で返ってくることを確認します。
サンプルコードには /items
というエンドポイントが用意されています。 こちらのエンドポイントをcurlで叩いてみます。
$ curl -X POST 'http://127.0.0.1:9000/items'
このエンドポイントは、コールに成功すると{"message": "item received: <name>"}
というレスポンスが返ってくることが期待されていますが、違ったレスポンスが返ってきてしまいます。
コマンドを以下のように修正することで、{"message": "item received: jacket"}
が返ってきますが、なぜそのような結果になるのか調べてみましょう。
$ curl -X POST \
--url 'http://localhost:9000/items' \
-d name=jacket
🔰 Point
- POSTとGETのリクエストの違いについて調べてみましょう
- ブラウザで
http://127.0.0.1:9000/items
にアクセスしても{"message": "item received: <name>"}
が返ってこないのはなぜでしょうか?- アクセスしたときに返ってくるHTTPステータスコードはいくつですか?
- それはどんな意味をもつステータスコードですか?
商品を登録するエンドポイントを作成します。
📖 Reference
- (JA)RESTful Web API の設計
- (JA)HTTP レスポンスステータスコード
- (EN) RESTful web API design
- (EN) HTTP response status codes
準備されているPOST /items
のエンドポイントはnameという情報を受け取れます。 ここにcategoryの情報も受け取れるように変更を加えます。
- name: 商品の名前 (string)
- category: 商品のカテゴリ(string)
このままではデータの保存ができないので、jsonファイルに保存するようにしましょう。
items.json
というファイルを作り、そこのitems
というキーに新しく登録された商品を追加するようにしましょう。
商品を追加すると、items.jsonの中身は以下のようになることを期待しています。
{"items": [{"name": "jacket", "category": "fashion"}, ...]}
GETで/items
にアクセスしたときに、登録された商品一覧を取得できるようにエンドポイントを実装しましょう。 以下のようなレスポンスを期待しています。
# 商品の登録
$ curl -X POST \
--url 'http://localhost:9000/items' \
-d 'name=jacket' \
-d 'category=fashion'
# /itemsにPOSTリクエストを送った時のレスポンス
{"message": "item received: jacket"}
# 登録された商品一覧
$ curl -X GET 'http://127.0.0.1:9000/items'
# /itemsにGETリクエストを送った時のレスポンス
{"items": [{"name": "jacket", "category": "fashion"}, ...]}
ここまでitems.json
に情報を保存してきましたが、このデータをデータベースに移し替えます。
今回は SQLiteというデータベースを使います。
📖 Reference
- (JA)SQLite入門
- (JA)Udemy -【SQLiteで学ぶ】ゼロから始めるデータベースとSQL超入門
- (JA)Udemy - はじめてのSQLserver データベース SQL未経験者〜初心者向けコース
- (EN)https://www.sqlitetutorial.net/
- (EN)Udemy - Intro To SQLite Databases for Python Programming
SQLiteをインストールし、dbフォルダに、mercari.sqlite3
というデータベースファイルを作成します。
mercari.sqlite3
を開き、items
テーブルを作成します。
itemsテーブルは以下のように定義し、スキーマを db/items.db
に保存します。
- id: int 商品ごとにユニークなID
- name: string 商品の名前
- category: string 商品のカテゴリ
データがデータベースに保存され、商品一覧情報を取り出すことができるように、GET /items
とPOST /items
のエンドポイントを変更しましょう。
items.db
はgitの管理対象にしますが、mercari.sqlite3
はgitの管理対象として追加しないようにしてください。
🔰 Point
- jsonファイルではなくデータベース(SQLite)にデータを保存する利点は何がありますか?
指定したキーワードを含む商品一覧を返す、GET /search
エンドポイントを作ります。
# "jacket"という文字を含む商品一覧をリクエストする
$ curl -X GET 'http://127.0.0.1:9000/search?keyword=jacket'
# "jacket"をnameに含む商品一覧が返ってくる
{"items": [{"name": "jacket", "category": "fashion"}, ...]}
商品情報に画像(image)を登録できるように、GET /items
とPOST /items
のエンドポイントを変更します。
- 画像は
images
というフォルダを作成し保存します - ポストされた画像を sha256 で hash化し、
<hash>.jpg
という名前で保存します - itemsテーブルに画像のファイル名をstringで保存できるように変更を加えます
# ディレクトリに保存された.jpgをポストする
curl -X POST \
--url 'http://localhost:9000/items' \
-d 'name=jacket' \
-d 'category=fashion' \
-d 'image=images/default.jpg'
Items table example:
id | name | category | image |
---|---|---|---|
1 | jacket | fashion | 510824dfd4caed183a7a7cc2be80f24a5f5048e15b3b5338556d5bbd3f7bc267.jpg |
2 | ... |
🔰 Point
- Hash化とはなにか?
- sha256以外にどんなハッシュ関数があるか調べてみましょう
商品の詳細情報を取得する GET /items/<item_id>
というエンドポイントを作成します。
$ curl -X GET 'http://127.0.0.1:9000/items/1'
{"name": "jacket", "category": "fashion", "image": "..."}
データベースを以下のように構成しなおします。
これによってカテゴリの名前が?途中で変わったとしても、全部のitemsテーブルのcategoryを修正する必要がなくなります。
GET items
ではcategoryの名前を変わらず取得したいので、テーブルをjoinしてレスポンス用のデータを作って返しましょう。
items table
id | name | category_id | image |
---|---|---|---|
1 | jacket | 1 | 510824dfd4caed183a7a7cc2be80f24a5f5048e15b3b5338556d5bbd3f7bc267.jpg |
2 | ... |
category table
id | name |
---|---|
1 | fashion |
... |
🔰 Point
- データベースの正規化とは何でしょうか?
http://127.0.0.1:9000/image/no_image.jpg
にアクセスしてみましょう。
no image
という画像が帰ってきますが、 コード中にある
Image not found: <image path>
というデバッグログがコンソールに表示されません。 これはなぜか、調べてみましょう。 これを表示するためには、どこを変更したらいいでしょうか?
🔰 Point
- Log levelとは?
- webサーバーでは、本番はどのログレベルまで表示する?
🔰 Point
以下のキーワードについて理解しましょう
- port (ポート番号)
- localhost, 127.0.0.1
- HTTPリクエストメソッド (GET, POST...)
- HTTPステータスコード (1XX, 2XX, 3XX, 4XX, 5XXはそれぞれどんな意味を持ちますか?)