Commit 3254a4ba by Carsten Brandt

Merge pull request #6684 from softark/docs-guide-ja-rest-update

Docs guide ja rest update [ci skip]
parents 50ea97bd a8523815
......@@ -131,11 +131,11 @@ RESTful ウェブサービス
* [クイックスタート](rest-quick-start.md)
* [リソース](rest-resources.md)
* [コントローラ](rest-controllers.md)
* **翻訳中** [ルーティング](rest-routing.md)
* **翻訳中** [レスポンスの書式設定](rest-response-formatting.md)
* **翻訳中** [認証](rest-authentication.md)
* **翻訳中** [転送レート制限](rest-rate-limiting.md)
* **翻訳中** [バージョン管理](rest-versioning.md)
* [ルーティング](rest-routing.md)
* [レスポンス形式の設定](rest-response-formatting.md)
* [認証](rest-authentication.md)
* [レート制限](rest-rate-limiting.md)
* [バージョン管理](rest-versioning.md)
* **翻訳中** [エラー処理](rest-error-handling.md)
......
認証
====
ウェブアプリケーションとは異なり、RESTful API は通常はステートレスです。
これは、セッションやクッキーは使用すべきでないことを意味します。
従って、ユーザの認証ステータスをセッションやクッキーで保持することが出来ないため、全てのリクエストに何らかの認証情報を付加する必要があります。
通常使われるのは、ユーザを認証するための秘密のアクセストークンを全てのリクエストとともに送信する方法です。
アクセストークンはユーザを一意に特定して認証することが出来るものですので、**API リクエストは、中間者攻撃 (man-in-the-middle attack) を防止するために、常に HTTPS 経由で送信されなければなりません**
アクセストークンを送信するには、いくつかの異なる方法があります。
* [HTTP Basic 認証](http://ja.wikipedia.org/wiki/Basic%E8%AA%8D%E8%A8%BC): アクセストークンはユーザ名として送信されます。
この方法は、アクセストークンを API コンシューマ側で安全に保存することが出来る場合、例えば API コンシューマがサーバ上で走るプログラムである場合などにのみ使用されるべきです。
* クエリパラメータ: アクセストークンは API の URL、例えば、`https://example.com/users?access-token=xxxxxxxx` でクエリパラメータとして送信されます。
ほとんどのウェブサーバはクエリパラメータをサーバのログに記録するため、この手法は、アクセストークンを HTTP ヘッダを使って送信することができない `JSONP` リクエストに応答するために主として使用されるべきです。
* [OAuth 2](http://oauth.net/2/): OAuth2 プロトコルに従って、アクセストークンはコンシューマによって権限付与サーバから取得され、[HTTP Bearer Tokens](http://tools.ietf.org/html/rfc6750) 経由で API サーバに送信されます。
Yii は上記の全ての認証方法をサポートしています。新しい認証方法を作成することも簡単に出来ます。
あなたの API に対して認証を有効にするためには、次のステップを実行します。
1. `user` アプリケーションコンポーネントを構成します。
- [[yii\web\User::enableSession|enableSession]] プロパティを `false` に設定します。
- [[yii\web\User::loginUrl|loginUrl]] プロパティを `null` に設定し、ログインページにリダイレクトする代りに HTTP 403 エラーを表示します。
2. REST コントローラクラスにおいて、`authenticator` ビヘイビアを構成することによって、どの認証方法を使用するかを指定します。
3. [[yii\web\User::identityClass|ユーザアイデンティティクラス]] において [[yii\web\IdentityInterface::findIdentityByAccessToken()]] を実装します。
ステップ 1 は必須ではありませんが、ステートレスであるべき RESTful API のために推奨されます。
[[yii\web\User::enableSession|enableSession]] が false である場合、ユーザの認証ステータスがセッションを使ってリクエストをまたいで存続することはありません。
その代りに、すべてのリクエストに対して認証が実行されます。このことは、ステップ 2 と 3 によって達成されます。
> Tip|情報: RESTful API をアプリケーションの形式で開発する場合は、アプリケーションの構成情報で `user` アプリケーションコンポーネントの [[yii\web\User::enableSession|enableSession]] プロパティを構成することが出来ます。
RESTful API をモジュールとして開発する場合は、次のように、モジュールの `init()` メソッドに一行を追加することが出来ます。
> ```php
public function init()
{
parent::init();
\Yii::$app->user->enableSession = false;
}
```
例えば、HTTP Basic 認証を使う場合は、`authenticator` ビヘイビアを次のように構成することが出来ます。
```php
use yii\filters\auth\HttpBasicAuth;
public function behaviors()
{
$behaviors = parent::behaviors();
$behaviors['authenticator'] = [
'class' => HttpBasicAuth::className(),
];
return $behaviors;
}
```
上で説明した三つの認証方法を全てサポートしたい場合は、次のように `CompositeAuth` を使うことが出来ます。
```php
use yii\filters\auth\CompositeAuth;
use yii\filters\auth\HttpBasicAuth;
use yii\filters\auth\HttpBearerAuth;
use yii\filters\auth\QueryParamAuth;
public function behaviors()
{
$behaviors = parent::behaviors();
$behaviors['authenticator'] = [
'class' => CompositeAuth::className(),
'authMethods' => [
HttpBasicAuth::className(),
HttpBearerAuth::className(),
QueryParamAuth::className(),
],
];
return $behaviors;
}
```
`authMethods` の各要素は、認証方法クラスの名前であるか、構成情報配列でなければなりません。
`findIdentityByAccessToken()` の実装はアプリケーション固有のものです。
例えば、各ユーザが一つだけアクセストークンを持ち得るような単純なシナリオでは、アクセストークンをユーザのテーブルの `access_token` カラムに保存することが出来ます。
そうすれば、次のように、`findIdentityByAccessToken()` メソッドを `User` クラスにおいて簡単に実装することが出来ます。
```php
use yii\db\ActiveRecord;
use yii\web\IdentityInterface;
class User extends ActiveRecord implements IdentityInterface
{
public static function findIdentityByAccessToken($token, $type = null)
{
return static::findOne(['access_token' => $token]);
}
}
```
上記のように認証が有効化された後は、全ての API リクエストに対して、リクエストされたコントローラが `beforeAction()` の段階でユーザを認証することを試みます。
認証が成功すると、コントローラはその他のチェック (レート制限、権限付与など) をしてから、アクションを実行します。
認証されたユーザのアイデンティティは `Yii::$app->user->identity` によって取得することが出来ます。
認証が失敗したときは、HTTP ステータス 401 およびその他の適切なヘッダ (HTTP Basic 認証に対する `WWW-Authenticate` ヘッダなど) を持つレスポンスが送り返されます。
## 権限付与 <a name="authorization"></a>
ユーザが認証された後、リクエストされたリソースに対してリクエストされたアクションを実行する許可を彼または彼女が持っているかどうかをチェックしたい場合があるでしょう。
*権限付与* と呼ばれるこのプロセスについては、[権限付与](security-authorization.md) のセクションで詳細に説明されています。
あなたのコントローラが [[yii\rest\ActiveController]] から拡張したものである場合は、[[yii\rest\Controller::checkAccess()|checkAccess()]] メソッドをオーバーライドして権限付与のチェックを実行することが出来ます。
このメソッドが [[yii\rest\ActiveController]] によって提供されている内蔵のアクションから呼び出されます。
......@@ -15,7 +15,7 @@ Yii 縺ッ縲ヽESTful 繧「繧ッ繧キ繝ァ繝ウ繧剃ス懈縺吶k莉穂コ九r邁。蜊倥↓縺吶k縺溘a縺
* HTTP メソッドのバリデーション
* [コンテントネゴシエーションとデータの書式設定](rest-response-formatting.md)
* [認証](rest-authentication.md)
* [転送レート制限](rest-rate-limiting.md)
* [レート制限](rest-rate-limiting.md)
[[yii\rest\ActiveController]] は次の機能を追加で提供します。
......@@ -47,12 +47,12 @@ public function actionView($id)
具体的に言うと、次のフィルタがリストされた順に従って実行されます。
* [[yii\filters\ContentNegotiator|contentNegotiator]]: コンテントネゴシエーションをサポート。
[レスポンスの書式設](rest-response-formatting.md) の節で説明します。
[レスポンス形式の設](rest-response-formatting.md) の節で説明します。
* [[yii\filters\VerbFilter|verbFilter]]: HTTP メソッドのバリデーションをサポート。
* [[yii\filters\AuthMethod|authenticator]]: ユーザ認証をサポート。
[認証](rest-authentication.md) の節で説明します。
* [[yii\filters\RateLimiter|rateLimiter]]: 転送レート制限をサポート。
[転送レート制限](rest-rate-limiting.md) の節で説明します。
* [[yii\filters\RateLimiter|rateLimiter]]: レート制限をサポート。
[レート制限](rest-rate-limiting.md) の節で説明します。
これらの名前付きのフィルタは、[[yii\rest\Controller::behaviors()|behaviors()]] メソッドで宣言されます。
このメソッドをオーバーライドして、個々のフィルタを構成したり、どれかを無効にしたり、あなた自身のフィルタを追加したりすることが出来ます。
......
......@@ -13,7 +13,7 @@ Yii は、RESTful ウェブサービス API を実装する仕事を簡単にす
* `OPTIONS` および `HEAD` 動詞のサポートを内蔵
* 認証と権限付与
* データキャッシュと HTTP キャッシュ
* 転送レート制限
* レート制限
以下においては、例を使って、どのようにして最小限のコーディング労力で一組の RESTful API を構築することが出来るかを説明します。
......@@ -182,7 +182,7 @@ Content-Type: application/json; charset=UTF-8
> Info|情報: 気がついたかも知れませんが、`http://localhost/users` の結果は、いくつかの公開すべきでないフィールド、例えば `password_hash` や `auth_key` を含んでいます。
> 当然ながら、これらが API の結果に出現することは避けたいでしょう。
> [レスポンスの書式設定](rest-response-formatting.md) の節で説明されているように、これらのフィールドを除外することは出来ますし、また、除外しなければなりません。
> [レスポンス形式の設定](rest-response-formatting.md) の節で説明されているように、これらのフィールドを除外することは出来ますし、また、除外しなければなりません。
## まとめ <a name="summary"></a>
......
レート制限
==========
悪用を防止するために、あなたの API に *レート制限* を加えることを検討すべきです。
例えば、各ユーザの API 使用を 10 分間で最大 100 回までの API 呼び出しに制限したいとしましょう。
ユーザから上記の期間内に多すぎるリクエストを受け取った場合は、ステータスコード 429 (「リクエストが多すぎる」の意味) を持つレスポンスを返すのです。
レート制限を可能にするためには、[[yii\web\User::identityClass|ユーザアイデンティティクラス]] で [[yii\filters\RateLimitInterface]] を実装しなければなりません。
このインタフェイスは次の三つのメソッドを実装することを要求します。
* `getRateLimit()`: 許可されているリクエストの最大数と期間を返します
(例えば、`[100, 600]` は 600 秒間に最大 100 回の API 呼び出しが出来ることを意味します)。
* `loadAllowance()`: 許可されているリクエストの残り数と、レート制限が最後にチェックされたときの対応する UNIX タイムスタンプを返します。
* `saveAllowance()`: 許可されているリクエストの残り数と現在の UNIX タイムスタンプの両方を保存します。
許容されているリクエスト数とタイムスタンプの情報を記録するために、ユーザのテーブルの二つのカラムを使うことが出来ます。
それらを定義すれば、`loadAllowance()``saveAllowance()` は、認証された現在のユーザに対応する二つのカラムの値を読み書きするものとして実装することが出来ます。
パフォーマンスを向上させるために、これらの情報の断片をキャッシュや NoSQL ストレージに保存することを検討しても良いでしょう。
アイデンティティのクラスに必要なインタフェイスを実装すると、Yii は [[yii\rest\Controller]] のアクションフィルタとして構成された [[yii\filters\RateLimiter]] を使って、自動的にレート制限のチェックを行うようになります。
レート制限を超えると、レートリミッタが [[yii\web\TooManyRequestsHttpException]] を投げます。
レートリミッタは、REST コントローラクラスの中で、次のようにして構成することが出来ます。
```php
public function behaviors()
{
$behaviors = parent::behaviors();
$behaviors['rateLimiter']['enableRateLimitHeaders'] = false;
return $behaviors;
}
```
レート制限が有効にされると、デフォルトでは、送信される全てのレスポンスに、現在のレート制限の情報を含む次の HTTP ヘッダが付加されます。
* `X-Rate-Limit-Limit` - 一定期間内に許可されるリクエストの最大数
* `X-Rate-Limit-Remaining` - 現在の期間において残っている許可されているリクエスト数
* `X-Rate-Limit-Reset` - 許可されているリクエストの最大数にリセットされるまで待たなければならない秒数
これらのヘッダは、上記のコード例で示されているように、[[yii\filters\RateLimiter::enableRateLimitHeaders]] を false に設定することで無効にすることが出来ます。
レスポンス形式の設定
====================
RESTful API のリクエストを処理するとき、アプリケーションは、通常、レスポンス形式の設定に関して次のステップを踏みます。
When handling a RESTful API request, an application usually takes the following steps that are related
with response formatting:
1. レスポンス形式に影響するさまざまな要因、例えば、メディアタイプ、言語、バージョンなどを決定します。
このプロセスは [コンテントネゴシエーション](http://en.wikipedia.org/wiki/Content_negotiation) としても知られるものです。
2. リソースオブジェクトを配列に変換します。
[リソース](rest-resources.md) の節で説明したように、この作業は [[yii\rest\Serializer]] によって実行されます。
3. 配列をコンテントネゴシエーションのステップで決定された形式の文字列に変換します。
この作業は、[[yii\web\Response::formatters|response]] アプリケーションコンポーネントに登録された [[yii\web\ResponseFormatterInterface|レスポンスフォーマッタ]] によって実行されます。
## コンテントネゴシエーション <a name="content-negotiation"></a>
Yii は [[yii\filters\ContentNegotiator]] フィルタによってコンテントネゴシエーションをサポートします。
RESTful API の基底コントローラクラス [[yii\rest\Controller]] は `contentNegotiator` という名前でこのフィルタを持っています。
このフィルタは、レスポンス形式のネゴシエーションと同時に言語のネゴシエーションも提供します。
例えば、RESTful API リクエストが下記のヘッダを含んでいるとします。
```
Accept: application/json; q=1.0, */*; q=0.1
```
この場合、リクエストは JSON 形式のレスポンスを受け取ることになります。例えば、次のような具合です。
```
$ curl -i -H "Accept: application/json; q=1.0, */*; q=0.1" "http://localhost/users"
HTTP/1.1 200 OK
Date: Sun, 02 Mar 2014 05:31:43 GMT
Server: Apache/2.2.26 (Unix) DAV/2 PHP/5.4.20 mod_ssl/2.2.26 OpenSSL/0.9.8y
X-Powered-By: PHP/5.4.20
X-Pagination-Total-Count: 1000
X-Pagination-Page-Count: 50
X-Pagination-Current-Page: 1
X-Pagination-Per-Page: 20
Link: <http://localhost/users?page=1>; rel=self,
<http://localhost/users?page=2>; rel=next,
<http://localhost/users?page=50>; rel=last
Transfer-Encoding: chunked
Content-Type: application/json; charset=UTF-8
[
{
"id": 1,
...
},
{
"id": 2,
...
},
...
]
```
舞台裏では、RESTful API コントローラアクションが実行される前に、[[yii\filters\ContentNegotiator]] フィルタがリクエストの `Accept` HTTP ヘッダをチェックして、[[yii\web\Response::format|レスポンス形式]] を `'json'` に設定します。
アクションが実行されて、その結果のリソースのオブジェクトまたはコレクションが返されると、[[yii\rest\Serializer]] が結果を配列に変換します。
そして最後に、[[yii\web\JsonResponseFormatter]] が配列を JSON 文字列に変換して、それをレスポンスボディに入れます。
デフォルトでは、RESTful API は JSON と XML の両方の形式をサポートします。
新しい形式をサポートするためには、下記のように、API コントローラクラスの中で `contentNegotiator` フィルタの [[yii\filters\ContentNegotiator::formats|formats]] プロパティを構成しなければなりません。
```php
use yii\web\Response;
public function behaviors()
{
$behaviors = parent::behaviors();
$behaviors['contentNegotiator']['formats']['text/html'] = Response::FORMAT_HTML;
return $behaviors;
}
```
`formats` プロパティのキーはサポートされる MIME タイプであり、値は対応するレスポンス形式名です。
このレスポンス形式名は、[[yii\web\Response::formatters]] の中でサポートされているものでなければなりません。
## データのシリアライズ <a name="data-serializing"></a>
上記で説明したように、[[yii\rest\Serializer]] が、リソースのオブジェクトやコレクションを配列に変換する際に、中心的な役割を果たします。
`Serializer` は、[[yii\base\ArrayableInterface]] および [[yii\data\DataProviderInterface]] のインタフェイスを実装したオブジェクトを認識します。
前者は主としてリソースオブジェクトによって実装され、後者はリソースコレクションによって実装されています。
[[yii\rest\Controller::serializer]] プロパティに構成情報配列をセットしてシリアライザを構成することが出来ます。
例えば、場合によっては、クライアントの開発作業を単純化するために、ページネーション情報をレスポンスボディに直接に含ませたいことがあるでしょう。
そうするためには、[[yii\rest\Serializer::collectionEnvelope]] プロパティを次のように構成します。
```php
use yii\rest\ActiveController;
class UserController extends ActiveController
{
public $modelClass = 'app\models\User';
public $serializer = [
'class' => 'yii\rest\Serializer',
'collectionEnvelope' => 'items',
];
}
```
このようにすると、`http://localhost/users` というリクエストに対して、次のレスポンスを得ることが出来ます。
```
HTTP/1.1 200 OK
Date: Sun, 02 Mar 2014 05:31:43 GMT
Server: Apache/2.2.26 (Unix) DAV/2 PHP/5.4.20 mod_ssl/2.2.26 OpenSSL/0.9.8y
X-Powered-By: PHP/5.4.20
X-Pagination-Total-Count: 1000
X-Pagination-Page-Count: 50
X-Pagination-Current-Page: 1
X-Pagination-Per-Page: 20
Link: <http://localhost/users?page=1>; rel=self,
<http://localhost/users?page=2>; rel=next,
<http://localhost/users?page=50>; rel=last
Transfer-Encoding: chunked
Content-Type: application/json; charset=UTF-8
{
"items": [
{
"id": 1,
...
},
{
"id": 2,
...
},
...
],
"_links": {
"self": "http://localhost/users?page=1",
"next": "http://localhost/users?page=2",
"last": "http://localhost/users?page=50"
},
"_meta": {
"totalCount": 1000,
"pageCount": 50,
"currentPage": 1,
"perPage": 20
}
}
```
ルーティング
============
リソースとコントローラのクラスが準備できたら、通常のウェブアプリケーションと同じように、`http://localhost/index.php?r=user/create` というような URL を使ってリソースにアクセスすることが出来ます。
実際には、綺麗な URL を有効にして HTTP 動詞を利用したいというのが普通でしょう。
例えば、`POST /users` というリクエストが `user/create` アクションへのアクセスを意味するようにしたいでしょう。
これは、アプリケーションの構成情報で `urlManager` アプリケーションコンポーネントを次のように構成することによって容易に達成することが出来ます。
```php
'urlManager' => [
'enablePrettyUrl' => true,
'enableStrictParsing' => true,
'showScriptName' => false,
'rules' => [
['class' => 'yii\rest\UrlRule', 'controller' => 'user'],
],
]
```
ウェブアプリケーションの URL 管理と比べたときに、上記で目に付く新しいことは、RESTful API リクエストのルーティングに [[yii\rest\UrlRule]] を使用していることです。
この特殊な URL 規則クラスが、一揃いの子 URL 規則を作成して、指定されたコントローラのルーティングと URL 生成をサポートします。
例えば、上記のコードは、おおむね下記の規則と等価です。
```php
[
'PUT,PATCH users/<id>' => 'user/update',
'DELETE users/<id>' => 'user/delete',
'GET,HEAD users/<id>' => 'user/view',
'POST users' => 'user/create',
'GET,HEAD users' => 'user/index',
'users/<id>' => 'user/options',
'users' => 'user/options',
]
```
そして、次の API エンドポイントがこの規則によってサポートされます。
* `GET /users`: 全てのユーザをページごとにリストする。
* `HEAD /users`: ユーザ一覧の概要を示す。
* `POST /users`: 新しいユーザを作成する。
* `GET /users/123`: ユーザ 123 の詳細を返す。
* `HEAD /users/123`: ユーザ 123 の概要情報を示す。
* `PATCH /users/123``PUT /users/123`: ユーザ 123 を更新する。
* `DELETE /users/123`: ユーザ 123 を削除する。
* `OPTIONS /users`: エンドポイント `/users` に関してサポートされる動詞を示す。
* `OPTIONS /users/123`: エンドポイント `/users/123` に関してサポートされる動詞を示す。
`only` および `except` オプションを構成すると、それぞれ、どのアクションをサポートするか、また、どのアクションを無効にするかを明示的に指定することが出来ます。
例えば、
```php
[
'class' => 'yii\rest\UrlRule',
'controller' => 'user',
'except' => ['delete', 'create', 'update'],
],
```
また、`patterns` あるいは `extraPatterns` を構成して、既存のパターンを再定義したり、この規則によってサポートされる新しいパターンを追加したりすることも出来ます。
例えば、エンドポイント `GET /users/search` によって新しいアクション `search` をサポートするためには、`extraPatterns` オプションを次のように構成します。
```php
[
'class' => 'yii\rest\UrlRule',
'controller' => 'user',
'extraPatterns' => [
'GET search' => 'search',
],
]
```
エンドポイントの URL ではコントローラ ID `user``users` という複数形で出現していることに気が付いたかもしれません。
これは、[[yii\rest\UrlRule]] が子 URL 規則を作るときに、コントローラの ID を自動的に複数形にするためです。
この振る舞いは [[yii\rest\UrlRule::pluralize]] を false に設定することで無効にすることが出来ます。
> Info|情報: コントローラ ID の複数形化は [[yii\helpers\Inflector::pluralize()]] によって行われます。
このメソッドは特殊な複数形の規則を考慮します。
例えば、`box` という単語の複数形は `boxs` ではなく `boxes` になります。
自動的な複数形化があなたの要求を満たさない場合は、[[yii\rest\UrlRule::controller]] プロパティを構成して、エンドポイント URL で使用される名前とコントローラ ID の対応を明示的に指定することも可能です。
例えば、次のコードはエンドポイント名 `u` をコントローラ ID `user` に割り当てます。
```php
[
'class' => 'yii\rest\UrlRule',
'controller' => ['u' => 'user'],
]
```
バージョン管理
==============
良い API は*バージョン管理* されています。
一つのバージョンを絶え間なく変更するのではなく、変更と新機能は API の新しいバージョンとして実装されます。
クライアント側とサーバ側の両方を完全に制御できるウェブアプリケーションとは違って、API はあなたの制御が及ばないクライアントによって使用されることを意図したものです。
このため、API の後方互換性 (BC) は、可能な限り保たれなければなりません。
BC を損なうかも知れない変更が必要な場合は、それを API の新しいバージョンにおいて導入し、バージョン番号を上げるべきです。
そうすれば、既存のクライアントは、API の古いけれども動作するバージョンを使い続けることが出来ますし、新しいまたはアップグレードされたクライアントは、新しい API バージョンで新しい機能を使うことが出来ます。
> Tip|ヒント: API のバージョン番号の設計に関する詳細情報は [Semantic Versioning](http://semver.org/) を参照してください。
API のバージョン管理を実装する方法としてよく使われるのは、バージョン番号を API の URL に埋め込む方法です。
例えば、`http://example.com/v1/users` が API バージョン 1 の `/users` エンドポイントを指す、というものです。
API のバージョン管理のもう一つの方法は、最近流行しているものですが、バージョン番号を HTTP リクエストヘッダに付ける方法です。
これは、典型的には、`Accept` ヘッダによって行われます。
```
// パラメータによって
Accept: application/json; version=v1
// ベンダーのコンテントタイプによって
Accept: application/vnd.company.myapp-v1+json
```
どちらの方法にも長所と短所があり、それぞれのアプローチに対して多くの議論があります。
下記では、この二つの方法をミックスした API バージョン管理の実際的な戦略を紹介します。
* API 実装の各メジャーバージョンを独立したモジュールに置き、モジュールの ID はメジャーバージョン番号 (例えば `v1``v2`) とします。
当然ながら、API の URL はメジャーバージョン番号を含むことになります。
* 各メジャーバージョンの中では (従って対応するモジュールの中では) `Accept` HTTP リクエストヘッダを使ってマイナーバージョン番号を決定し、マイナーバージョンに応じたレスポンスのための条件分岐コードを書きます。
各モジュールが一つのメジャーバージョンを提供しますので、モジュールは指定されたバージョンのためのリソースとコントローラのクラスを含んでいなければなりません。
コードの責任範囲をより良く分離するために、共通の基底のリソースとコントローラのクラスを保持して、それをバージョンごとの個別のモジュールでサブクラス化することが出来ます。
サブクラスの中で、`Model::fields()` のような具体的なコードを実装します。
あなたのコードを次のように組織することが出来ます。
```
api/
common/
controllers/
UserController.php
PostController.php
models/
User.php
Post.php
modules/
v1/
controllers/
UserController.php
PostController.php
models/
User.php
Post.php
Module.php
v2/
controllers/
UserController.php
PostController.php
models/
User.php
Post.php
Module.php
```
アプリケーションの構成情報は次のようなものになります。
```php
return [
'modules' => [
'v1' => [
'class' => 'app\modules\v1\Module',
],
'v2' => [
'class' => 'app\modules\v2\Module',
],
],
'components' => [
'urlManager' => [
'enablePrettyUrl' => true,
'enableStrictParsing' => true,
'showScriptName' => false,
'rules' => [
['class' => 'yii\rest\UrlRule', 'controller' => ['v1/user', 'v1/post']],
['class' => 'yii\rest\UrlRule', 'controller' => ['v2/user', 'v2/post']],
],
],
],
];
```
上記のコードの結果として、`http://example.com/v1/users` はバージョン 1 のユーザ一覧を返し、`http://example.com/v2/users` はバージョン 2 のユーザ一覧を返すことになります。
モジュールのおかげで、異なるメジャーバージョンのためのコードは、きれいに分離することが可能です。
しかし、モジュール化しても、共通の基底クラスやその他の共有リソースを通じて、モジュール間でコードを再利用することは引き続いて可能です。
マイナーバージョン番号を扱うためには、[[yii\filters\ContentNegotiator|contentNegotiator]] ビヘイビアによって提供されるコンテントネゴシエーションの機能を利用することが出来ます。
`contentNegotiator` ビヘイビアは、どのコンテントタイプをサポートするかを決定するときに、[[yii\web\Response::acceptParams]] プロパティをセットします。
例えば、リクエストが HTTP ヘッダ `Accept: application/json; version=v1` を伴って送信された場合、コンテントネゴシエーションの後では、[[yii\web\Response::acceptParams]] に `['version' => 'v1']` という値が含まれています。
`acceptParams` のバージョン情報に基づいて、アクション、リソースクラス、シリアライザなどの個所で条件付きのコードを書いて、適切な機能を提供することが出来ます。
マイナーバージョンは、定義上、後方互換性を保つことを要求するものですので、コードの中でバージョンチェックをする個所はそれほど多くないものと期待されます。
そうでない場合は、たいていは、新しいメジャーバージョンを作成する必要がある、ということです。
......@@ -46,7 +46,7 @@ Composer 縺後う繝ウ繧ケ繝医繝ォ縺輔l縺溘i縲√え繧ァ繝悶°繧峨い繧ッ繧サ繧ケ縺ァ縺阪
必要なら別のディレクトリ名を選ぶことも出来ます。
> Note|注意: インストール実行中に Composer が あなたの Github のログイン認証情報を求めることがあるかも知れません。
> これは、Comoser が依存パッケージの情報を Github から読み出すために十分な転送レートを必要とするためで、普通にあることです。
> これは、Comoser が依存パッケージの情報を Github から読み出すために十分な API レートを必要とするためで、普通にあることです。
> 詳細については、[Composer ドキュメント](https://getcomposer.org/doc/articles/troubleshooting.md#api-rate-limit-and-oauth-tokens) を参照してください。
> Tip|ヒント: Yii の最新の開発バージョンをインストールしたい場合は、[stability option](https://getcomposer.org/doc/04-schema.md#minimum-stability) を追加した次のコマンドを代りに使うことが出来ます。
......
......@@ -283,8 +283,8 @@ PageCache の使用に関する詳細は [ページキャッシュ](caching-page
### [[yii\filters\RateLimiter|RateLimiter]] <a name="rate-limiter"></a>
RateLimiter は [リーキーバケットアルゴリズム](http://ja.wikipedia.org/wiki/%E3%83%AA%E3%83%BC%E3%82%AD%E3%83%BC%E3%83%90%E3%82%B1%E3%83%83%E3%83%88)
に基づいて転送レート制限のアルゴリズムを実装するものです。主として RESTful API を実装するときに使用されます。
このフィルタの使用に関する詳細は [転送レート制限](rest-rate-limiting.md) の節を参照してください。
に基づいてレート制限のアルゴリズムを実装するものです。主として RESTful API を実装するときに使用されます。
このフィルタの使用に関する詳細は [レート制限](rest-rate-limiting.md) の節を参照してください。
### [[yii\filters\VerbFilter|VerbFilter]] <a name="verb-filter"></a>
......
......@@ -396,7 +396,7 @@ $array = $post->attributes;
このメソッドの既定の動作は [[yii\base\Model::$attributes]] のそれと同じものです。
しかしながら、このメソッドを使うと、どのデータ項目 (*フィールド* と呼ばれます)
を結果の配列に入れるか、そして、その項目にどのような書式を適用するかを選ぶことが出来ます。
実際、[レスポンスの書式設定](rest-response-formatting.md) で説明されているように、RESTful
実際、[レスポンス形式の設定](rest-response-formatting.md) で説明されているように、RESTful
ウェブサービスの開発においては、これがモデルをエクスポートする既定の方法となっています。
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment