PowerCMS™

PowerCMS ブログ

ホーム > PowerCMS ブログ > Data API エンドポイントの実装(独自オブジェクトのData API対応)

2015年03月09日

Data API エンドポイントの実装(独自オブジェクトのData API対応)

Data API エンドポイントの実装(独自オブジェクトのData API対応)

MT6.1で強化されたData APIですが、PowerCMSのバナー、カスタムオブジェクト等の対応を進めています。既に実装は完了しておりテスト段階ですが、この記事では「独自オブジェクトやData API未対応のオブジェクトに対するプラグインによるエンドポイントの実装方法を簡単に纏めておきます。

※以下のプラグインは現在 β版です。

各オブジェクトに対して基本的に実装すべきものとしては「リスト取得」「単一オブジェクト取得」「作成」「更新」「削除」でしょう。オブジェクトによっては「検索」等も必要になってくると思います。

操作routeverb
リスト取得/sites/:site_id/campaignsGET
単一オブジェクト取得/sites/:site_id/campaigns/:campaign_idGET
作成/sites/:site_id/campaignsPOST
更新/sites/:site_id/campaigns/:campaign_idPUT(or POST with __method=PUT)
削除/sites/:site_id/campaigns/:campaign_idDELETE(or POST with __method=DELETE)

config.yaml への endpoints の指定

applications:
    data_api:
        endpoints:
            -
                handler: DataAPIPowerCMS::DataAPI::_data_api_endpoint_campaigns
                id: data_api_campaigns
                requires_login: 0
                route: '/sites/:site_id/campaigns'
                verb: GET
                version: 1
            -
                handler: DataAPIPowerCMS::DataAPI::_data_api_endpoint_get_campaign
                id: data_api_get_campaign
                requires_login: 0
                route: '/sites/:site_id/campaigns/:campaign_id'
                verb: GET
                version: 1
            -
                handler: DataAPIPowerCMS::DataAPI::_data_api_endpoint_create_campaign
                id: data_api_create_campaign
                requires_login: 1
                route: '/sites/:site_id/campaigns'
                verb: POST
                version: 1
            -
                handler: DataAPIPowerCMS::DataAPI::_data_api_endpoint_create_campaign
                id: data_api_update_campaign
                requires_login: 1
                route: '/sites/:site_id/campaigns/:campaign_id'
                verb: PUT
                version: 1
            -
                handler: DataAPIPowerCMS::DataAPI::_data_api_endpoint_delete_campaign
                id: data_api_delete_campaign
                requires_login: 1
                route: '/sites/:site_id/campaigns/:campaign_id'
                verb: DELETE
                version: 1

requires_loginについては、作成、更新、削除については1を指定し、パーミッションのチェックはコード内で行ないます。取得については、0を指定し、オブジェクトにstatusカラムのあるオブジェクトの場合、ログインしていないユーザーもしくは権限のないユーザの場合はステータスが2(公開)状態のもののみを返し、オブジェクトに関する権限を有するユーザーに対してはすべてのオブジェクトを返すようにすると良いでしょう。

エンドポイントのコード

モジュール内では、MT::DataAPI::Endpoint::Common と MT::DataAPI::Resource を use宣言します。以下は単一オブジェクトの取得の例です。

use MT::DataAPI::Endpoint::Common;
use MT::DataAPI::Resource;

sub _data_api_endpoint_get_campaign {
    my ( $app, $endpoint ) = @_;
    my ( $blog, $campaign ) = context_objects( @_ ) or return;
    # $blog に MT::Blog(Website) オブジェクト、#campaign には
    # '/sites/:site_id/campaigns/:campaign_id' の:campaign_idに指定された ID の
    # Campaign オブジェクトが格納されます。
    my $class = 'campaign';
    run_permission_filter( $app, 'data_api_view_permission_filter', $class ) or return;
    # プラグインで権限チェックをカスタマイズできるようにする
    my $user = $app->user;
    if ( $user ) {
        if (! __permission( $user, $blog, $class ) ) {
            # 権限を有するユーザーかチェックする
            $user = undef;
        }
    }
    if ( (! $user ) && ( $campaign->status != 2 ) ) {
        return;
    }
    return $campaign;
}

create、update 等のコードの例は、以下のようなものです。

sub _data_api_endpoint_create_campaign {
    my ( $app, $endpoint ) = @_;
    my ( $blog, $campaign ) = context_objects( @_ ) or return;
    require Campaign::Plugin;
    require Campaign::Campaign;
    if (! Campaign::Plugin::_campaign_permission( $blog ) ) {
        return;
    }
    my $author = $app->user;
    my $orig_campaign = $campaign;
    if (! $orig_campaign ) {
        # context_objects で Campaignオブジェクトが取得できない場合、新規作成
        $orig_campaign = $app->model( $class )->new;
        $orig_campaign->set_values(
            {   blog_id   => $blog->id,
                author_id => $author->id,
            }
        );
    }
    my $new_campaign = $app->resource_object( 'campaign', $orig_campaign )
        or return;
    # $app->resource_object で、渡された JSON を Campaign オブジェクトに変換
    # 
    # 中略
    #
    save_object( $app, 'campaign', $new_campaign, $orig_campaign, ) or return;
    # save_object でオブジェクトの作成/更新(保存)。
    # data_api_pre_save.campaign、data_api_post_save.campaign コールバックは 
    # save_object から自動的にコールされるが、システムログへの保存は自前で書く必要が
    # あります。
    return $new_campaign; # 最後に作成(更新)されたオブジェクトを返します。

config.yaml への resources の指定

        resources:
            campaign:
                fields:
                    - id
                    - title
                    - text
                    - blog_id
                    - image_id
                    - movie_id
                    - memo
                    - publishing_on
                    - period_on
                    - created_on
                    - modified_on
                    - banner_width
                    - banner_height
                    - name: banner
                      from_object: DataAPIPowerCMS::DataAPI::get_banner
                    - name: movie
                      from_object: DataAPIPowerCMS::DataAPI::get_movie
                    - name: customFields
                      from_object: DataAPIPowerCMS::DataAPI::customFields
                      to_object: DataAPIPowerCMS::DataAPI::to_customFields
                    - name: author
                      type: MT::DataAPI::Resource::DataType::Object
                      fields:
                        - id
                        - displayName
                        - userpicUrl
                    - name: image_width
                      from_object: DataAPIPowerCMS::DataAPI::image_width
                    - name: image_height
                      from_object: DataAPIPowerCMS::DataAPI::image_height
                    - name: status
                      from_object: DataAPIPowerCMS::DataAPI::status_text
                      to_object: DataAPIPowerCMS::DataAPI::to_status
                    - name: tags
                      from_object: DataAPIPowerCMS::DataAPI::tags
                      to_object: DataAPIPowerCMS::DataAPI::to_tags
                updatable_fields: 
                    - title
                    - text
                    - memo
                    - publishing_on
                    - period_on
                    - created_on
                    - modified_on
                    - banner_width
                    - banner_height
                    - status
                    - tags
                    - customFields

fields にレスポンス JSON に含めるカラムを updatable_fields にアップデート可能なカラムを指定して行きます。ここで注意したいのは、標準のカラムでないもの(タグやカスタムフィールド)や整形して格納するもの(ステータス等)を from_object、to_object に指定し、データを組み立てたり格納するコードをプラグイン側に書くことです。カスタムフィールドを組み立てたり、ステータスを数字ではなく「Publiching」「Draft」等の文字列で扱うなどの調整をコードで行ないます。

JSONに渡されたステータス文字列(例: Publishing)を数字に変換して status カラムに格納するコードは以下のようになります。

sub to_status {
    my ( $hash, $obj ) = @_;
    if ( my $status = $hash->{ status } ) {
        $status = __status_int( $status );
        $hash->{ status } = $status;
        $obj->status( $status );
    }
    return;
}

sub __status_int {
    my $status = shift;
    $status = uc( $status );
    return 1 if $status eq 'DRAFT' || $status eq 'HOLD';
    return 2 if $status eq 'PUBLISHED' || $status eq 'PUBLISHING' || $status eq 'RELEASE';
    return 3 if $status eq 'RESERVED' || $status eq 'FUTURE';
    return 4 if $status eq 'FINISED' || $status eq 'CLOSED' || $status eq 'ENDED';
    return 0;
}

カテゴリー
PowerCMS 4
技術情報

Recent Entries