RESTful API ドキュメント (概説)

目次

準備

https://example.com/powercmsx/api/ 配下のリクエストを https://example.com/powercmsx/api/index.php に渡すように設定します。パスはカスタマイズ可能です。その場合はindex.php内のパスを環境にあわせて書き換えてください。

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php [L]
</IfModule>

スコープの設定画面とモデルの編集画面で「APIを有効化」にチェックを入れることで、利用可能になります。

モデル設定画面でのRESTful APIの有効化

認証(authentication)エンドポイントについては環境変数「api_allow_login」指定のある場合に利用可能になります(初期値true)。

エンドポイントへのアクセス

authentication エンドポイントは以下のパス

/api/バージョン/authentication

それ以外のエンドポイントは以下の形のパスとなります

/api/バージョン/スコープID/モデル名/メソッド/オブジェクトID(オプション)?キー1=値1&キー2=値2...

環境変数

idプロパティの値は「RESTfulAPI」です。

通常の config.json, AppPropertiesプラグインでの管理画面での登録のほか、アプリケーションディレクトリ直下に api-config.json に以下のようにキー : 値の形式で指定することが可能です。Webアクセスができないようにしてください。

{
    "api_allow_login" : true,
    "api_list_limit" : 25,
    "api_methods": {
        "1" : {
            "entry" : ["list", "get"]
        }
    }
}
  • api_methods : スコープ・モデルに対して利用可能にするエンドポイントを制限したい場合にスコープのIDをキーにして配列で指定します。スペース 1 に対して list, getエンドポイントのみを許可する場合、以下のように指定します。

"api_methods": {
    "1" : {
        "entry" : ["list", "get"]
    }
}
  • api_list_limit : listエンドポイントで limit指定のない時のデフォルト返却件数を指定します。初期値は 10です。
  • api_name_column : authenticationエンドポイントで nameパラメタに対応するユーザーのカラム名を指定します。初期値は nameです。
  • api_password_column : authenticationエンドポイントで nameパラメタに対応するユーザーのカラム名を指定します。初期値は passwordです。
  • api_sess_expires : authenticationエンドポイントで取得したアクセストークンの有効期限秒を指定します。初期値は 3600です。
  • api_caching : APIのレスポンスをキャッシュします。初期値は trueです。
  • api_cache_methods : 初期値は[‘list’, ‘get’, ‘search’, ‘scheme’]です。
  • api_contains_username : 各エンドポイントから返却される JSONでオブジェクトの作成者情報のうち、ユーザー名を除去します。初期値は trueです。
  • api_contains_useremail : 各エンドポイントから返却される JSONでオブジェクトの作成者情報のうち、メールアドレスを除去します。初期値は trueです。
  • api_unescaped_unicode : 各エンドポイントから返却される JSON生成時に「JSON_UNESCAPED_UNICODE」オプションを追加します。
  • api_pretty_print : 各エンドポイントから返却される JSON生成時に「JSON_PRETTY_PRINT」オプションを追加します。
  • api_allow_login : authenticationエンドポイントを有効化します。初期値は trueです。
  • api_debug : RESTful API のデバッグ時に指定します。指定時には api_unescaped_unicode, api_pretty_print は有効化され、GETリクエストで POSTリクエストのテストを行うことが可能になります。
  • api_debug_user_id : api_debugが有効な時、アクセストークンやクッキーがなくてもそのユーザーとして振る舞います。
  • api_debug_json_path : api_debugが有効な時、リクエストボディにセットする JSONの代わりに、指定したパスの JSONファイルをデータとして利用します。
  • api_user_lockout : authenticationエンドポイントで認証に失敗した時、システム設定のルールに基づきユーザーをロックアウトします。初期値は trueです。
  • api_ip_lockout : authenticationエンドポイントで認証に失敗した時、システム設定のルールに基づき IPアドレスをロックアウトします。初期値は falseです。
  • api_use_cookie : アクセストークンに加えて authenticationエンドポイントで認証した時にクッキーを発行し、その後の認証付きリクエスト時にクッキーをあわせてチェックします。初期値は falseです。
  • api_cookie_name : api_use_cookieが有効な時に発行するクッキー名です。初期値は「pt-api-user」です。
  • api_allow_remember : authenticationエンドポイントで認証の有効期限を 1年延長する remember追加パラメタを許可します。初期値は falseです。
  • api_allow_contact : 「contact」モデルが「APIを有効化」に設定されていない時にも「token」「confirm」「submit」エンドポイントの利用を許可します。初期値は trueです。
  • api_status_text : オブジェクトJSONの返却時にステータスを数値ではなくテキストで返却します。
  • api_requires_login : get, listエンドポイントで認証を必要とするモデルを配列で指定します。初期値は['log', 'contact', 'activity', 'permission', 'role', 'searchword']です。

※ 不特定多数がアクセスできる環境では絶対に「api_debug」「api_debug_user_id」を指定しないでください。

オブジェクトJSON

返却されるオブジェクトJSONの形は基本的に以下のフォーマットです。list/searchエンドポイントではキー「items」に配列で返却されます。

{
    "id" : "オブジェクトID",
    "カラム名1" : "カラム1の値",
    "カラム名2" : "カラム2の値"
}

リレーションを含むオブジェクトJSON

リレーションを含むオブジェクトJSONのフォーマットは以下の通りです。関連オブジェクトのさらに関連オブジェクトについては展開されません。

{
    "id" : "オブジェクトID",
    "カラム名1" : "カラム1の値",
    "数値型単一リレーションカラム" : {
        "id" : "オブジェクトID",
        "カラム名1" : "カラム1の値",
        "カラム名2" : "カラム2の値"
    },
    "複数リレーション型カラム" : [
        {
            "id" : "オブジェクトID",
            "カラム名1" : "カラム1の値",
            "カラム名2" : "カラム2の値"
        },
        {
            "id" : "オブジェクトID",
            "カラム名1" : "カラム1の値",
            "カラム名2" : "カラム2の値"
        }
    ]
}

メタデータ

オブジェクトのカラムの値やリレーションによる関連オブジェクトのカラムの値以外のデータをメタデータと呼びます。 メタデータのキーは、必ず大文字で始まります。メタデータには以下のものがあります。

  • Url : カラム名のキーに対する配列内に設定されます。バイナリ型のカラムにファイルを添付している時、その URLです。
  • Label : カラム名のキーに対する配列内に設定されます。バイナリ型のカラムにファイルを添付している時、そのラベルまたは代替テキストです。
  • Metadata : カラム名のキーに対する配列内に設定されます。バイナリ型のカラムにファイルを添付している時、そのファイルに関する情報の配列です。
  • Permalink : オブジェクトのパーマリンクです。URLマップによるアーカイブのあるときは優先アーカイブの URL、URLマップがなくバイナリ型のカラムにファイルを添付している時は、1つめのファイルの URLです。
  • Thumbnail : 環境変数「assets_c」「assets_c_path」を指定して、静的にサムネイルファイルを出力している時はその URL、静的サムネイルがない時、認証付きで権限のあるユーザーに対しては動的サムネイルの URLとなります。動的サムネイルの URLに「square=1」パラメタをつけると、正方形のサムネイルを返します。
  • Path : 階層付きオブジェクトの場合、basenameカラムの存在するモデルでは「basename」を、そうでないモデルについてはプライマリカラムの値を「/」で区切ったパスをセットします。
  • Fields : オブジェクトのフィールドにセットされた値の配列です。
  • Meta : フィールド、バイナリ型のカラムのファイル情報以外のメタデータの配列です。
  • Workflow : 「approval(承認依頼)」または「remand(差し戻し)」
  • Message : ワークフロー通知に含めるメール用のメッセージ

バイナリデータ(ファイル)の送信

例えば、記事にバイナリ型のカラムを追加している時、以下のようにして(Data URI schemeの形式で)ファイルのデータを送信します。

{
    "id" : "オブジェクトID",
    "og_image" : {
        "Label" : "ラベルまたは代替テキスト",
        "Data" : "data:image/png;base64,..................."
    }
}

アセットと添付ファイルについては、記事などのリレーションデータとして登録できます。「Path」にはサイト・パスを「%r」として相対パスを指定します。「Path」が指定できるのはアセットのみで、添付ファイルについては保存場所は自動で設定されます。

{
    "title": "Welcome!",
    "assets": [
        {
            "file": {
                "Label" : "ラベルまたは代替テキスト",
                "Data": "data:image/png;base64,...................",
                "Path": "%r/assets/filename.png"
            }
        }
    ]
}

アセットの関連付けの解除、添付ファイルの削除には「Detach」を指定します。「id」をあわせて指定しなければなりません。
添付ファイルの場合は、そのファイルを削除、アセットの場合には、そのアセットは削除されず、関連付けのみが解除されます。数値型単一選択のリレーション型にも対応しています。

{
    "title": "Welcome!",
    "assets": [
        {
            "id":23,
            "Detach":true
        }
    ]
}

contactモデルの confirm/submitエンドポイントに送信するときは、ファイル名、設問のベースネームを付けて送信します。

{
    "Identifier": "contact_us",
    "Language": "ja",
    "Permalink":"https:\/\/localhost\/01\/contact\/website_contact_us.html",
    "website_your_name": "野田純生",
    "website_email": "webmaster@alfasado.jp",
    "website_subject": "テスト投稿",
    "website_message": "テスト投稿です",
    "website_privacy_policy": "agree",
    "attachmentfiles": [
        {
            "name": "ファイル名.docx",
            "basename": "website_attachment1",
            "file": {
                "Data": "data:application\/vnd.openxmlformats-officedocument.wordprocessingml.document;base64,............"
            }
        }
    ]
}

ステータス(status)に指定可能な値

ステータスには数値以外に文字列でも指定できます。環境変数「status_text」に指定がある場合はテキストで返却されます。

有効期限対応指定のあるモデルの場合

  • 0 : 「Draft」(下書き)
  • 1 : 「Review」(レビュー)
  • 2 : 「Approval Pending」(承認待ち)
  • 3 : 「Reserved」(公開予約)
  • 4 : 「Publish」(公開)
  • 5 : 「Ended」(終了)

有効期限対応指定のないモデルの場合

  • 1 : 「Disable」(無効)
  • 2 : 「Enable」(有効)

insert, updateメソッドにおけるワークフローの利用

insert, updateでワークローを利用するには以下のルールでオブジェクトJSONを指定します。モデルがワークフローに対応していて、そのスコープでワークフローが設定されていることが必要です。

  • user_id : 承認依頼または差し戻すユーザーのID
  • status : 異なる権限グループのユーザーへ渡す時は、そのユーザーが指定できるステータス以下の値
  • Workflow : 「approval(承認依頼)」または「remand(差し戻し)」
  • Message : ワークフロー通知に含めるメール用のメッセージ
{
    "user_id"  : ユーザーのID,
    "status"   : ユーザーに応じたステータス,
    "Workflow" : "approval",
    "Message"  : "メールに含めるメッセージのテキスト",
}

ワークフロー対応モデルのステータスの数字は以下の通りです。

  • 0 : 下書き
  • 1 : レビュー
  • 2 : 承認待ち
  • 3 : 公開予約
  • 4 : 公開
  • 5 : 終了

権限グループによって指定できるステータスの最大値は以下の通りです(カッコ内は異なるグループのユーザーへ渡す時に指定する値)。

  • 作成者(creator) : 0 (0)
  • レビュワー(reviewer) : 1 (1)
  • 公開者(publisher) : 5 (2)

ワークフローの設定がない時、ワークフローで渡すことのできるユーザー以外のIDを指定した時、上記のステータスより大きな値の数字を渡したときは権限エラーとなります。

{
    "status": 403,
    "message": "Permission denied."
}

insert, update メソッドでのリビジョンの指定

リビジョンを指定するには「rev_type」「rev_object_id」を指定します。rev_type=1 が自動保存、rev_type=2 がリビジョンです。

{
    "rev_type" : 1または2,
    "rev_object_id" : マスタのID
}

マスタが存在しない時、マスタとリビジョンのスコープが違うときはエラーとなります。マスタを update メソッドでリビジョンに変更することはできません。

プラグインによる RESTful APIへのメソッドの追加

プラグインによって RESTful APIへメソッドを追加することができます。

config.json

{
    "label": "RESTfulAPIEndPoint",
    "id": "restfulapiendpoint",
    "component": "RESTfulAPIEndPoint",
    "description": "Provides RESTful API Custom EndPoint.",
    "version": "1.0",
    "author": "Alfasado Inc.",
    "author_link": "https://alfasado.net/",
    "api_methods": {
        "v1" : {
            "custom_end_point": {
                "component": "RESTfulAPIEndPoint",
                "method": "custom_end_point",
                "permission": "create_entry",
                "allowed" : [
                    "PUT",
                    "POST"
                ]
            }
        }
    }
}

RESTfulAPIEndPoint.php

<?php
require_once( LIB_DIR . 'Prototype' . DS . 'class.PTPlugin.php' );

class RESTfulAPIEndPoint extends PTPlugin {

    function __construct () {
        parent::__construct();
    }

    function custom_end_point ( $app ) {
        // $app は PTRESTfulAPIv1 クラス
        // $app->id は 'RESTfulAPI'
        // $app->json_error( 'An error has occurred.', 403 );
        // $app->json_error( 'An error has occurred(%s).', 'Error Messaage', 403 );
        $json = [];
        $app->print_json( $json );
    }
}

フックとコールバック

  • フックは管理画面と同様に動作します。
  • insert, update, delete 時には管理画面の save, deleteメソッド実行時のコールバックが呼ばれます。
  • ファイルのパブリッシュ時は publish_callbacks 関連のコールバックが呼ばれます。

モデル restfulapi に対する「pre_response」コールバックを登録することで、レスポンスを返す直前のデータの配列にアクセスできます。

$app->init_callbacks( 'restfulapi', 'pre_response' );
$callback = ['name' => 'pre_response'];
$this->run_callbacks( $callback, 'restfulapi', $json );

第3引数 &$json をカスタマイズすることで、そのデータを返します。

function pre_response ( $cb, $app, &$json ) {
}