Web API
Web API とは、Web 上のシステム間インターフェース、つまりデータを受け渡しするための規約のことです。この Web API を実装することで、ブラウザなどから HTTP や HTTPS を通じてデータの受け渡しができるようになります。
Web API はサービス提供側が自由に実装するわけですが、多くのクラウドサービスでは、デザイン思想は REST スタイル、データフォーマットは JSON の Web API が提供されています。
Web API をスキャフォールディング
TreeFrog では、1つテーブルからデータを CRUD する Web API の足場を簡単に作ることができます。
例えば、次のようなテーブルがあったとします。
sqlite> .schema blog
CREATE TABLE blog (id INTEGER PRIMARY KEY AUTOINCREMENT, title VARCHAR(20), body VARCHAR(200), created_at TIMESTAMP, updated_at TIMESTAMP, lock_revision INTEGER);
このテーブルに対して、次のコマンドで Web API の足場を作ります。
$ tspawn api blog
DriverType: QSQLITE
DatabaseName: db/dbfile
HostName:
Database opened successfully
created models/sqlobjects/blogobject.h
created models/objects/blog.h
created models/objects/blog.cpp
updated models/models.pro
created models/apiblogservice.h
created models/apiblogservice.cpp
updated models/models.pro
created controllers/apiblogcontroller.h
created controllers/apiblogcontroller.cpp
updated controllers/controllers.pro
コントローラやサービスクラスなどのソースファイルが生成されました。ここで作られる Web API のデータフォーマットは JSON になります。
Web API のエントリーポイントは次のようにコントローラ apiblogcontroller.h
に定義されます。
class T_CONTROLLER_EXPORT ApiBlogController : public ApplicationController {
Q_OBJECT
public slots:
void index(); // 一覧取得
void get(const QString &id); // 1件取得
void create(); // 新規登録
void save(const QString &id); // 保存(更新)
void remove(const QString &id); // 1件削除
};
これらのエントリーポイントは次のとおりです。
/apiblog/index
/apiblog/get/(id)
/apiblog/create
/apiblog/save/(id)
/apiblog/remove/(id)
Web API の動作確認
ソースをビルドし、サーバを起動します。
$ make
$ treefrog -e dev -d
curl コマンドで Web API の動作確認してみましょう。
$ curl -sS http://localhost:8800/apiblog/index
{"data":[]}
何もデータが登録されていないので、空の JSON データが取得されました。
エントリーポイント追加
デフォルトのエントリーポイントに加え、config/routes.cfg
に項目を記述することでエントリーポイントを追加することができます。例えば、次のように記述します。
# Method Entry-point Function
get /api/blog/index ApiBlog.index
get /api/blog/get/:param ApiBlog.get
post /api/blog/create ApiBlog.create
post /api/blog/save/:param ApiBlog.save
post /api/blog/remove/:param ApiBlog.remove
正しく追加されたかをチェックします。
$ treefrog --show-routes
Available routes:
get /api/blog/index -> apiblogcontroller.index()
get /api/blog/get/:param -> apiblogcontroller.get(id)
post /api/blog/create -> apiblogcontroller.create()
post /api/blog/save/:param -> apiblogcontroller.save(id)
post /api/blog/remove/:param -> apiblogcontroller.remove(id)
GET や POST の他に PUT や DELETE も追加することができます。詳しくは URL ルーティング のページを参照してください。
curl コマンドで追加したエントリーポイントの動作確認してみましょう。
$ curl -sS http://localhost:8800/api/blog/index ← 追加したエントリーポイント
{"data":[]}
同じように、空の JSON データを取得することができました。
登録用の Web API
次にデータを 1 件登録してみましょう。curl コマンドで JSON データを POST します。
$ curl -sS -X POST -H "Content-Type: application/json" -d '{"title":"Hello","body":"hello world"}' http://localhost:8800/api/blog/create
もう一度、一覧を取得してみます。
$ curl -sS http://localhost:8800/api/blog/index
{"data":[{"body":"hello world","createdAt":"2022-05-25T16:39:02.142","id":1,"lockRevision":1,"title":"Hello","updatedAt":"2022-05-25T16:39:02.142"}]}
今後は一覧のデータを正しく取得できました。
ID を指定してデータを取得してみましょう。
$ curl -sS http://localhost:8800/api/blog/get/1
{"data":{"body":"hello world","createdAt":"2022-05-25T16:39:02.142","id":1,"lockRevision":1,"title":"Hello","updatedAt":"2022-05-25T16:39:02.142"}}
正しく取得できました。
返却するプロパティを制限する
スキャフォールディング後のソースでは、DB レコードのカラムの全データが返却されていましたが、返却データ(プロパティ)を制限してみましょう。
サービスクラス apiblogservice.cpp
を編集します。
QJsonObject ApiBlogService::index()
{
auto blogList = Blog::getAll();
QJsonObject json = { {"data", tfConvertToJsonArray(blogList, {"id", "title", "body"})} }; // ←ここ
return json;
}
QJsonObject ApiBlogService::get(int id)
{
auto blog = Blog::get(id);
QJsonObject json = { {"data", blog.toJsonObject({"id", "title", "body"})} }; // ←ここ
return json;
}
ビルド後に、curl コマンドで確認してみると、指定したプロパティのみ返却されています。
$ curl -sS http://localhost:8800/api/blog/index
{"data":[{"body":"hello world","id":1,"title":"Hello"}]}
$ curl -sS http://localhost:8800/api/blog/get/1
{"data":{"body":"hello world","id":1,"title":"Hello"}}
まとめ
スキャフォールディングでシンプルな Web API を作成することができました。
実際のケースでは、このスキャフォールディングで作られた実装では不十分でしょう。例えば、2 つ以上のテーブルからデータを取得し、階層化された JSON データを返すことがあります。その場合はサービスクラスなどを適宜修正して、実装してください。