Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
Y
yii2
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
PSDI Army
yii2
Commits
3893bcd0
Commit
3893bcd0
authored
May 18, 2014
by
Qiang Xue
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
guide WIP [skip ci]
parent
ce12ddb6
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
80 additions
and
54 deletions
+80
-54
rest-resources.md
docs/guide/rest-resources.md
+7
-8
rest-response-formatting.md
docs/guide/rest-response-formatting.md
+71
-44
ContentNegotiator.php
framework/filters/ContentNegotiator.php
+2
-2
No files found.
docs/guide/rest-resources.md
View file @
3893bcd0
...
@@ -22,15 +22,14 @@ then all its public member variables will be returned.
...
@@ -22,15 +22,14 @@ then all its public member variables will be returned.
## Fields <a name="fields"></a>
## Fields <a name="fields"></a>
When a resource object is sent in response to a RESTful API request, it involves the following two steps:
When including a resource in a RESTful API response, the resource needs to be serialized into a string.
Yii breaks this process into two steps. First, the resource is converted into an array by
[
[yii\rest\Serializer
]
].
1.
The object is converted into an array by
[
[yii\rest\Serializer
]
]. This is the focus of this section.
Second, the array is serialized into a string in a requested format (e.g. JSON, XML) by
2.
The array is serialized into a string in a requested format (e.g. JSON, XML) by
[
[yii\web\ResponseFormatterInterface|response formatters
]
]. The first step is what you should mainly focus when
[
[yii\web\ResponseFormatterInterface|response formatters
]
]. This will be the focus of
developing a resource class.
the
[
Response Formatting
](
rest-response-formatting.md
)
section.
By overriding
[
[yii\base\Model::fields()|fields()
]
] and/or
[
[yii\base\Model::extraFields()|extraFields()
]
],
By overriding
[
[yii\base\Model::fields()|fields()
]
] and/or
[
[yii\base\Model::extraFields()|extraFields()
]
],
you may specify what data, called
*fields*
, in the resource can be put in
the array representation of a resource object
.
you may specify what data, called
*fields*
, in the resource can be put in
to its array representation
.
The difference between these two methods is that the former specifies the default set of fields which should
The difference between these two methods is that the former specifies the default set of fields which should
be included in the array representation, while the latter specifies additional fields which may be included
be included in the array representation, while the latter specifies additional fields which may be included
in the array if an end user requests for them via the
`expand`
query parameter. For example,
in the array if an end user requests for them via the
`expand`
query parameter. For example,
...
@@ -50,7 +49,7 @@ http://localhost/users?fields=id,email&expand=profile
...
@@ -50,7 +49,7 @@ http://localhost/users?fields=id,email&expand=profile
```
```
### Overriding `fields()` <a name="overriding-fi
le
ds"></a>
### Overriding `fields()` <a name="overriding-fi
el
ds"></a>
By default,
[
[yii\base\Model::fields()
]
] returns all model attributes as fields, while
By default,
[
[yii\base\Model::fields()
]
] returns all model attributes as fields, while
[
[yii\db\ActiveRecord::fields()
]
] only returns the attributes which have been populated from DB.
[
[yii\db\ActiveRecord::fields()
]
] only returns the attributes which have been populated from DB.
...
...
docs/guide/rest-response-formatting.md
View file @
3893bcd0
Response Formatting
Response Formatting
===================
===================
As described in the
[
Resources
](
rest-resources.md
)
section, we have shown how to specify what data a resource
When handling a RESTful API request, an application usually takes the following steps that are related
can expose through RESTful APIs. In this section, we will describe the behind-the-scene work regarding how a
with response formatting:
resource is being turned into a string in the format that is requested by end users. We will also describe
the possible options that you have in order to customize this process.
1.
Determine various factors that may affect the response format, such as media type, language, version, etc.
This process is also known as
[
content negotiation
](
http://en.wikipedia.org/wiki/Content_negotiation
)
.
2.
Convert resource objects into arrays, as described in the
[
Resources
](
rest-resources.md
)
section.
This is done by
[
[yii\rest\Serializer
]
].
3.
Convert arrays into a string in the format as determined by the content negotiation step. This is
done by
[
[yii\web\ResponseFormatterInterface|response formatters
]
] registered with
the
[
[yii\web\Response::formatters|response
]
] application component.
individual
## Content Negotiation <a name="content-negotiation"></a>
there are two steps involved in formatting response data.
Yii supports content negotiation via the
[
[yii\filters\ContentNegotiator
]
] filter. The the RESTful API base
The first step is to convert resources or resource collections into arrays, and the second step is to serialize
controller class
[
[yii\rest\Controller
]
] is equipped with this filter under the name of
`contentNegotiator`
.
the arrays into strings in the requested format. The first step has been covered in the
[
Resources
](
rest-resources.md
)
The filer provides response format negotiation as well as language negotiation. For example, if a RESTful
section. In this section, we will mainly describe the second step.
API request contains the following header,
By default, Yii supports two response formats for RESTful APIs: JSON and XML. If you want to support
```
other formats, you should configure the
`contentNegotiator`
behavior in your REST controller classes as follows,
Accept: application/json; q=1.0, */*; q=0.1
```
it will get a response in JSON format, like the following:
```
$ 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,
...
},
...
]
```
Behind the scene, before a RESTful API controller action is executed, the
[
[yii\filters\ContentNegotiator
]
]
filter will check the
`Accept`
HTTP header in the request and set the
[
[yii\web\Response::format|response format
]
]
to be
`'json'`
. After the action is executed and returns the resulting resource object or collection,
[
[yii\rest\Serializer
]
] will convert the result into an array. And finally,
[
[yii\web\JsonResponseFormatter
]
]
will serialize the array into a JSON string and include it in the response body.
By default, RESTful APIs support both JSON and XML formats. To support a new format, you should configure
the
[
[yii\filters\ContentNegotiator::formats|formats
]
] property of the
`contentNegotiator`
filter like
the following in your API controller classes:
```
php
```
php
use yii\
helpers\ArrayHelper
;
use
yii\
web\Response
;
public
function
behaviors
()
public
function
behaviors
()
{
{
return ArrayHelper::merge(parent::behaviors(), [
$behaviors
=
parent
::
behaviors
();
'contentNegotiator' => [
$behaviors
[
'contentNegotiator'
][
'formats'
][
'text/html'
]
=
Response
::
FORMAT_HTML
;
'formats' => [
return
$behaviors
;
// ... other supported formats ...
],
],
]);
}
}
```
```
Formatting response data in general involves two steps:
The keys of the
`formats`
property are the supported MIME types, while the values are the corresponding
response format names which must be supported in
[
[yii\web\Response::formatters
]
].
1.
The objects (including embedded objects) in the response data are converted into arrays by
[
[yii\rest\Serializer
]
];
2.
The array data are converted into different formats (e.g. JSON, XML) by
[
[yii\web\ResponseFormatterInterface|response formatters
]
].
Step 2 is usually a very mechanical data conversion process and can be well handled by the built-in response formatters.
Step 1 involves some major development effort as explained below.
When the
[
[yii\rest\Serializer|serializer
]
] converts an object into an array, it will call the
`toArray()`
method
of the object if it implements
[
[yii\base\Arrayable
]
]. If an object does not implement this interface,
its public properties will be returned instead.
You may wonder who triggers the conversion from objects to arrays when an action returns an object or object collection.
The answer is that this is done by
[
[yii\rest\Controller::serializer
]
] in the
[
[yii\base\Controller::afterAction()|afterAction()
]
]
method. By default,
[
[yii\rest\Serializer
]
] is used as the serializer that can recognize resource objects extending from
[
[yii\base\Model
]
] and collection objects implementing
[
[yii\data\DataProviderInterface
]
]. The serializer
will call the
`toArray()`
method of these objects and pass the
`fields`
and
`expand`
user parameters to the method.
If there are any embedded objects, they will also be converted into arrays recursively.
If all your resource objects are of
[
[yii\base\Model
]
] or its child classes, such as
[
[yii\db\ActiveRecord
]
],
## Data Serializing <a name="data-serializing"></a>
and you only use
[
[yii\data\DataProviderInterface
]
] as resource collections, the default data formatting
implementation should work very well. However, if you want to introduce some new resource classes that do not
extend from
[
[yii\base\Model
]
], or if you want to use some new collection classes, you will need to
customize the serializer class and configure
[
[yii\rest\Controller::serializer
]
] to use it.
You new resource classes may use the trait
[
[yii\base\ArrayableTrait
]
] to support selective field output
as explained above.
As we have described above,
[
[yii\rest\Serializer
]
] is the central piece responsible for converting resource
objects or collections into arrays. It recognizes objects implementing
[
[yii\base\ArrayableInterface
]
] as
well as
[
[yii\data\DataProviderInterface
]
]. The former is mainly implemented by resource objects, while
the latter resource collections.
Sometimes, you may want to help simplify the client development work by including pagination information
You may configure the serializer by setting the
[
[yii\rest\Controller::serializer
]
] property with a configuration array.
For example, sometimes you may want to help simplify the client development work by including pagination information
directly in the response body. To do so, configure the
[
[yii\rest\Serializer::collectionEnvelope
]
] property
directly in the response body. To do so, configure the
[
[yii\rest\Serializer::collectionEnvelope
]
] property
as follows:
as follows:
...
...
framework/filters/ContentNegotiator.php
View file @
3893bcd0
...
@@ -89,7 +89,7 @@ class ContentNegotiator extends ActionFilter implements BootstrapInterface
...
@@ -89,7 +89,7 @@ class ContentNegotiator extends ActionFilter implements BootstrapInterface
* @var string the name of the GET parameter that specifies the response format.
* @var string the name of the GET parameter that specifies the response format.
* Note that if the specified format does not exist in [[formats]], a [[UnsupportedMediaTypeHttpException]]
* Note that if the specified format does not exist in [[formats]], a [[UnsupportedMediaTypeHttpException]]
* exception will be thrown. If the parameter value is empty or if this property is null,
* exception will be thrown. If the parameter value is empty or if this property is null,
* the response format will be determined based on the `Accept` HTTP header.
* the response format will be determined based on the `Accept` HTTP header
only
.
* @see formats
* @see formats
*/
*/
public
$formatParam
=
'_format'
;
public
$formatParam
=
'_format'
;
...
@@ -97,7 +97,7 @@ class ContentNegotiator extends ActionFilter implements BootstrapInterface
...
@@ -97,7 +97,7 @@ class ContentNegotiator extends ActionFilter implements BootstrapInterface
* @var string the name of the GET parameter that specifies the [[\yii\base\Application::language|application language]].
* @var string the name of the GET parameter that specifies the [[\yii\base\Application::language|application language]].
* Note that if the specified language does not match any of [[languages]], the first language in [[languages]]
* Note that if the specified language does not match any of [[languages]], the first language in [[languages]]
* will be used. If the parameter value is empty or if this property is null,
* will be used. If the parameter value is empty or if this property is null,
* the application language will be determined based on the `Accept-Language` HTTP header.
* the application language will be determined based on the `Accept-Language` HTTP header
only
.
* @see languages
* @see languages
*/
*/
public
$languageParam
=
'_lang'
;
public
$languageParam
=
'_lang'
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment