« YAPC::Fukuoka 2017 HAKATA で「Web API の未来」を話してきた | メインページ | ブログ記事を聴こう »

2022年12月 2日

Movable Type の OpenAPI スキーマ対応をご存知ですか?

こんにちは。こちらは Movable Type Advent Calendar 2022 向けの記事です。

改めまして、こんにちは。重田です。(公開当初は名乗っていなかったので)

Advent Calendar 初参加なのでお手柔らかにお願いします!

先日 MTDDC Meetup TOKYO 2022キーノートでも触れられていましたが、次期 Movable Type が2023年秋にリリースされるそうです。Movable Type 8 となり、その機能概要も公開されました。

その機能概要の新機能・機能強化でも触れられていますが、

OpenAPI JSON Schema にはすでに対応済 (r.5201)

とありますようにすでに Movable Type に OpenAPI スキーマを出力する機能がついているのをご存知でしょうか?

そこで今回は OpenAPI スキーマについて紹介します。

Movable Type の OpenAPI スキーマ

OpenAPI スキーマのエンドポイントには MTDataAPIScript (デフォルトでは mt-data-api.cgi)に v1 〜 5 のバージョンを付与してアクセスします。

例えば管理画面の URL が https://app.example.com/cgi-bin/mt/mt.cgi の場合、おおよそ次のような URL になります。

  • https://app.example.com/cgi-bin/mt/mt-data-api.cgi/v1/
  • https://app.example.com/cgi-bin/mt/mt-data-api.cgi/v2/
  • https://app.example.com/cgi-bin/mt/mt-data-api.cgi/v3/
  • https://app.example.com/cgi-bin/mt/mt-data-api.cgi/v4/
  • https://app.example.com/cgi-bin/mt/mt-data-api.cgi/v5/

それぞれのバージョンで対応しているリソースが異なりますので、バージョンごとにスキーマも異なります。

JSON 形式でレスポンスが返ってきます。この JSON のフォーマットは OpenAPI Specification に準拠しています。

これまでの一般的な ウェブサービスの REST API を利用する場合、送信パラメータやレスポンスの内容はそのウェブサービスの公式ドキュメントを読んでから利用することが多かったと思います。それを汎用的な JSON スキーマ形式で提供してクライアント側やサーバ側で利用しやすいように定義したのが OpenAPI スキーマです。

OpenAPI スキーマには送信パラメータやレスポンスの型情報も含まれているので、Data API クライアントを自作する場合に入力値の検証やレスポンス値の利用もより安全になると思います。

Movable Type のドキュメントサイト開発者ポータルでも REST API のドキュメントを提供しています。バージョンごとに API リファレンスを提供していますが、これらも OpenAPI スキーマをベースに生成しています。

このようにプログラムからだけでなくドキュメント生成まで API に関することを幅広く利用できるのが OpenAPI スキーマのメリットだと思います。

OpenAPI スキーマを利用する

早速、OpenAPI スキーマを利用して Data API を試してみたいと思います。人気があるツールでもある Swagger UI を紹介します。

Swagger UI

Swagger UI は OpenAPI スキーマを出力するエンドポイントの URL を入力すると自動的に API 一覧を生成しプレイグラウンドとして API を利用できます。(Swagger UI のライブデモ があります。エンドポイントに https://petstore.swagger.io/v2/swagger.json を指定して API の一覧を表示しています。)

同じように Movable Type の OpenAPI スキーマを利用して Data API を体験してみましょう。

個人的に Swagger UI を利用するのに手っ取り早いと感じるのは Docker を使うやり方です。Swagger UI のインストールドキュメントに Docker の章がありますので参照してみてください。

docker コマンドで起動できましたら画面上部の URL 入力フォームにご自身の Movable Type の OpenAPI スキーマのエンドポイント(例: https://app.example.com/cgi-bin/mt/mt-data-api.cgi/v5/ )を入力し Explore ボタンを押すと Movable Type Data API のエンドポイント一覧が読み込まれます。

40-Screen Shot 2022-11-30 at 11.41.26.png

認証

Movable Type の開発者ポータルにあるクイックスタートガイドのユーザー認証とアクセストークンの章にありますが、Data API で直接サインインする場合は POST http(s)://path/to/mt-data-api.cgi/v2/authentication を使います。

そして得られたアクセストークンを使います。クイックスタートガイドにありますように

アクセストークンは、X-MT-Authorization リクエストヘッダーに MTAuth accessToken=<ACCESS_TOKEN>という形式で指定します。

とありますので、Swagger UI の認証(鍵のアイコン)のところで以下のダイアログが出ましたら、入力フォームのところには MTAuth accessToken=アクセストークン を入力してください。

44-Screen Shot 2022-11-30 at 16.57.23.png

これで認証が必要な API も利用できるようになると思います。

OpenAPI テーマ

ご自身で Docker で Swagger UI を立ち上げる以外の方法として Movable Type のテーマを作ってみました。

これは Swagger UI Dist を利用したインデックスページのみを作るテーマです。

Data API の動作確認用のウェブサイトを作り、このテーマを適用するとインデックスページが Swagger UI が適用されたページとなります。インデックステンプレートに


url: '<$mt:AdminCGIPath$><$mt:DataAPIScript$>/v5/',

と記述されていますので、動作確認用のウェブサイトの URL で Data API v5 のエンドポイントが自動的に設定されます。

開発用途でお使いいただくのに便利だと思います。

41-Screen Shot 2022-11-30 at 11.52.09.png

OpenAPI スキーマから Data API クライアントを作る

Swagger UI でも十分に Data API の体験ができますが、OpenAPI スキーマをさらに利用してみたいと思います。

Data API は主にプログラムから利用すると思います。

OpenAPI スキーマから各種プログラミング言語用のクライアントを生成するツールがありますのでそれを紹介します。

有名どころとしては OpenAPI Generator だと思います。

試した環境は次の通りです。


% sw_vers
ProductName:	macOS
ProductVersion:	11.6.8
BuildVersion:	20G730

まずは OpenAPI スキーマを JSON ファイルとしてダウンロードします。


% curl -o v5.json https://api.example.com/cgi-bin/mt/mt-data-api.cgi/v5/

次に OpenAPI Generator のインストールの Docker の章を参考に実行します。今回は Python でクライアントを作ってみましょう。(プログラミング言語はいろいろ対応しています)


% docker run --rm \
  -v ${PWD}:/local openapitools/openapi-generator-cli generate \
  -i /local/v5.json \
  -g python \
  -o /local/out/python

docker image の作成や実際に open-api-cli 生成する間しばらく待つと out/python ディレクトリに作成されます。


% du -hs out
 16M	out
% find out/python -type f | wc -l
    1352

とても大量でした......

とりあえず試してみます。


% cd out/python
% virtualenv -p python3 env
% source env/bin/activate
% pip install -r requirements.txt

必要なライブラリは pip でインストールしました。

out/python/README.md の Getting Started にコードのサンプルがあるのでコピペします。(インデントや構文エラーがあったのでそれは修正しました)


import time
import openapi_client
from pprint import pprint
from openapi_client.apis.tags import assets_api
from openapi_client.model.asset import Asset
from openapi_client.model.asset_updatable import AssetUpdatable
from openapi_client.model.entry import Entry
from openapi_client.model.error_content import ErrorContent
from openapi_client.model.page import Page

configuration = openapi_client.Configuration(
    host = "https://api.example.com/mt/mt-data-api.cgi/v5"
)

configuration.api_key['mtauth'] = 'YOUR_API_KEY'

with openapi_client.ApiClient(configuration) as api_client:
    # Create an instance of the API class
    api_instance = assets_api.AssetsApi(api_client)
    overwrite_once = 0 # int | If specify \"1\", the API always overwrites an existing file with the uploaded file. This parameter has been available since Movable Type 6.1.2 (optional)
    body = dict(
        auto_rename_if_exists=0,
        auto_rename_non_ascii=0,
        file=open('/path/to/file', 'rb'),
        normalize_orientation=1,
        path="path_example",
        site_id=1,
    ) # {str: (bool, date, datetime, dict, float, int, list, str, none_type)} |  (optional)

    try:
        # Upload a file
        api_response = api_instance.assets_upload_post(overwrite_once=overwrite_once, body=body)
        pprint(api_response)
    except openapi_client.ApiException as e:
        print("Exception when calling AssetsApi->assets_upload_post: %s\n" % e)

では実行してみます。


% python myclient.py
ModuleNotFoundError: No module named 'openapi_client.model.asset_updatable'

ん?モジュールがない?


% ls openapi_client/model/asset*
openapi_client/model/asset.py   openapi_client/model/asset.pyi

grep しても asset_updatable クラスの定義がない......。ということで、Python はあまり相性がよくなさそうですね......。

気を取り直して Perl で試してみました。結論から言うと Perl では無事に実行できました。


% docker run --rm \
  -v ${PWD}:/local openapitools/openapi-generator-cli generate \
  -i /local/v5.json \
  -g perl \
  -o /local/out/perl
% cd out/perl
% vi cpanfile
% cat cpanfile
requires 'Class::Accessor';
requires 'Class::Data::Inheritable';
requires 'DateTime';
requires 'Log::Any';
requires 'LWP::Protocol::https';
requires 'URI::Query';
% carton install
% vi myclient.pl
% cat myclient.pl
use WWW::OpenAPIClient::AuthenticationApi;
use WWW::OpenAPIClient::AssetsApi;
use Data::Dumper;

my $auth_instance = WWW::OpenAPIClient::AuthenticationApi->new;
my $auth_obj = $auth_instance->authentication_post(
    client_id => 'test',
    password => 'fjz5mcws',
    username => 'Melody', 
);
my $access_token = $auth_obj->access_token;

my $api_instance = WWW::OpenAPIClient::AssetsApi->new(
    api_key => {'X-MT-Authorization' => "MTAuth accessToken=$access_token"},
);

my $overwrite_once = 1;
my $auto_rename_if_exists = 0;
my $auto_rename_non_ascii = 1;
my $file = "movable-type-logo.png";
my $normalize_orientation = 1;
my $path = "path_example";
my $site_id = 1;

eval {
    my $result = $api_instance->assets_upload_post(overwrite_once => $overwrite_once, auto_rename_if_exists => $auto_rename_if_exists, auto_rename_non_ascii => $auto_rename_non_ascii, file => $file, normalize_orientation => $normalize_orientation, path => $path, site_id => $site_id);
    print Dumper($result);
};
if ($@) {
    warn "Exception when calling AssetsApi->assets_upload_post: $@\n";
}
% perl -I lib -I local/lib/perl myclient.pl

こちらも out/perl/README.md をほぼコピペしています。違いとしては WWW::OpenAPIClient::AuthenticationApi を使ってアクセストークンを取得した点とそのアクセストークンを WWW::OpenAPIClient::AssetsApi->new の引数に渡したところです。Swagger UI のところでもお伝えしました通り、Movable Type Data API はリクエストヘッダに X-MT-Authorization: MTAuth accessToken=アクセストークン (API によっては sessonId の場合もあります)を渡す必要があります。

クラス名など色々と怪しい部分もありますが、OpenAPI Generator はあくまで雛形作成であって、生成後は自身でカスタマイズしていく方向のようですね。とっかかりとしては便利かもしれません。

まとめ

この記事で Movable Type が OpenAPI スキーマに対応したことや OpenAPI スキーマの利用用途について簡単にお話ししました。

Movable Type が OpenAPI スキーマに対応したことで Data API を利用する環境がより身近になったと思います。Movable Type Advent Calendar 2022 の1日目の Yoshiki Kato さんの記事『Astro.js と Movable Type Data API を使用して Jamstack な Blog を作ってみる | WWW WATCH』でも Jamstack が触れらていましたが、Movable Type Data API が Jamstack をはじめとする様々な API エコノミーの選択肢に入るようになるとうれしいです。もし Movable Type Data API を活用する機会があれば各種ソーシャルネットワークやブログなどでぜひ紹介してくださいね!

Happy coding!

See Also

ja で話します。