BLOG

Go to top


Movable Type 6 の Data API と関連するコールバックや拡張カラムの扱いなど

August 4, 2013 11:01 PM

あんまりにも久しぶりすぎて、ブログの書き方から復習が必要でした。

Movable Type 6 に実装される Data API を試してみた人もいると思います。発表前に触れる機会をいただいていたにも関わらずインストールする時間すら取れない有様だったので、少しでも触れておくことと、まだドキュメントは親切と言える内容でもなさそうなので、多少なりとも自分と同じようなポジションの方々の役に立てればと...あと、僕のこと忘れ去られないようにと...

概要

まず、Data API においてリクエストを受け付けてくれる CGI は(デフォルトでは)mt-data-api.cgi です。処理の実体は MT::App::DataAPI で、/path/to/mt/lib/MT/App/DataAPI.pm がこれにあたります。

MT::App::DataAPI は MT::App を継承したアプリケーションで、その点は mt-comments.cgi や mt-search.cgi はもちろん mt.cgi とも変わることはありません。なので、以下のようなコールバックは mt-data-api.cgi にも実行されます。

  • MT::App::DataAPI::init_request
  • MT::App::DataAPI::init_app
  • MT::App::DataAPI::pre_run
  • MT::App::DataAPI::post_run
  • MT::App::DataAPI::take_down

プラグインの registry に登録するときは「MT::App::DataAPI::」を省略することもできますが、その場合は mt-data-api.cgi だけでなく、mt.cgi や mt-comments.cgi でも動作します。

この他に、mt-data-api.cgi に特有のものとして、以下のコールバックも実行されます。

  • pre_run_data_api(MT::App::DataAPI::pre_run の後)
  • post_run_data_api(MT::App::DataAPI::pre_run の前)

mt-data-api.cgi については公式に各エンドポイントとその説明が上がっています。比較的ベーシックな、API に慣れた人には扱いやすい形式だと思います。エンドポイントについては MT::App::DataAPI::core_endpoints にデフォルトのエンドポイントの指定があります。対応するハンドラもここを見ればわかります。

リクエストの仕方についてはすでに様々な方が言及されていると思うので簡略化しますが、たとえば、ID が 1 のブログに記事を新規に作成する場合、このページのように、「https://example.com/mt/mt-data-api.cgi/v1/sites/1/entries」に POST します。Perl でやるなら以下のような感じです。
※ $accessToken は、認証によって得られるレスポンスの「accessToken」です


my $endpoint = $api_url . "/sites/1/entries";
my $params = {
    'entry' => MT::Util::to_json( { title => 'Hello by DataAPI: ' . MT::Util::log_time(),
                                    body => 'This is test',
                                    status => 'Draft',
                                  },
                                ),
};
my $request = HTTP::Request->new( 'POST', $endpoint );
$request->header( 'X-MT-Authorization' => "MTAuth accessToken=$accessToken" );
$request->content( join( '&', map { $_ . '=' . $params->{ $_ } } keys %$params ) );
my $ua = MT->new_ua;
my $res = $ua->request( $request );
unless ( $res->is_success ) {
    if ( $res->code == 500 ) {
        my $content = MT::Util::from_json( $res->content );
        my $message = $content->{ error }->{ message };
        $message =~ s/\\x{([0-9a-z]+)}/chr(hex($1))/ge;
        die $message;
    } else {
        die $res->as_string;
    }
}
my $content = MT::Util::from_json( $res->content );

公式ドキュメントにはステータスコード 500 は載っていませんが、たとえば送信したパラメータが正しくない場合等に「不正な要求です」という応答が返るようです。そういうケースへの対応の方が時間を要することが多いので、上記には参考までにエラーメッセージの取り出し方の記述を含めました。

上記では最低限のカラムしかデータを入れていません。カスタムフィールドや、プラグインによって拡張したカラムについては以下のようにします。

なお、返されるオブジェクトの情報について、以下のように fields パラメータで指定することにより、必要なフィールドのみに絞ることができます。この点は各エンドポイントに共通のようです。


/sites/$blog_id/entries?fields=id,title
/sites/$blog_id/entries/$entry_id?fields=id,title

カスタムフィールドを更新する場合

以下のように、customFields の指定を追加します。これは、/path/to/mt/addons/Commercial.pack/lib/CustomFields/DataAPI.pm の CustomFields::DataAPI::fields に記述があるのですが、より端的にはカスタムフィールドを作成した後で上記を実行すると得られる返却値の形を見る方が早いでしょう。


my $params = {
    'entry' => MT::Util::to_json( { title => 'Hello by DataAPI: ' . MT::Util::log_time(),
                                    body => 'This is test',
                                    status => 'Draft',
                                    customFields => [
                                        {
                                          basename => 'text',
                                          value => 'teeeeeeeeeeeeext',
                                        }
                                    ],
                                  },
                                ),
};

プラグインによって拡張したカラムを更新したい場合

こちらはカスタムフィールドと同じというわけにはいきません。以下では、「foo」カラムを追加し、それを mt-data-api.cgi 経由で更新できるようにする例です。

まず、config.yaml に以下のように記述します。


object_types:
    entry:
        foo: string(255)
applications:
    data_api:
        resources:
            entry:
                fields:
                    - name: foo
                      from_object_default: bar
                updatable_fields:
                    - foo

object_types はこれまでの Movable Type でも必要だったカラム拡張に関する指定です。合わせて schema_version を指定することでアップグレードが行われ、mt_entry にカラム foo が追加されます。

applications 以下の指定が今回必要になる指定です。entry に対して「fields」と「updatable_fields」を指定しています。「fields」はレスポンスに含めるために、「updatable_fields」は mt-data-api.cgi 経由で更新できるようにするための指定です。「field」の「from_object_default」に指定した値はデフォルト値になります。「updatable_fields」が指定されていない場合、foo カラムの値は常に「from_object_default」になります。
このあたりは、/path/to/mt/lib/MT/DataAPI/Resource/Entry.pm の MT::DataAPI::Resource::Entry::fields や MT::DataAPI::Resource::Entry::updatable_fields にデフォルトのものがあるので、これを参考に、プラグインから registry に指定していくことになります。

これを指定した上で、以下のようにリクエストを送ることで foo カラムにデータを投入することができます。


my $params = {
    'entry' => MT::Util::to_json( { title => 'Hello by DataAPI: ' . MT::Util::log_time(),
                                    body => 'This is test',
                                    status => 'Draft',
                                    foo => 'foooooooooooo!',
                                  },
                                ),
};

オブジェクトの保存、削除等に関連するコールバック

これまでもコミュニティ機能などで使われていた API 経由での保存に準じて以下のようなコールバックが実行されるようです。他にもあると思いますが、ベーシックなところだけ。

  • data_api_save_filter.entry
  • data_api_pre_save.entry
  • data_api_post_save.entry
  • data_api_post_delete.entry

Data API に関する所感

自分に関係がありそうなところを少し調べてみた、触ってみたという程度でまだ試せていないプロパティなどたくさんありますが、総じてスッキリとした形で扱いやすそうな印象を持っています。
なお、今回、Data API について調べるのに使ったプラグインを GitHub に公開しています。認証から、エントリーの作成、更新、削除、ログアウトまでを一連の動作として行うツールも入れてあります。参考になれば。

Comments


Contact me

Copyright © 2005 - 2017 okayama All rights reserved.