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 データを返すことがあります。その場合はサービスクラスなどを適宜修正して、実装してください。



