rest-quick-start.md 7.04 KB
Newer Older
Qiang Xue committed
1 2
Quick Start
===========
Qiang Xue committed
3

Qiang Xue committed
4
Yii provides a whole set of tools to simplify the task of implementing RESTful Web Service APIs.
Qiang Xue committed
5
In particular, Yii supports the following features about RESTful APIs:
Qiang Xue committed
6

Qiang Xue committed
7
* Quick prototyping with support for common APIs for [Active Record](db-active-record.md);
8
* Response format negotiation (supporting JSON and XML by default);
Qiang Xue committed
9 10
* Customizable object serialization with support for selectable output fields;
* Proper formatting of collection data and validation errors;
Qiang Xue committed
11
* Support for [HATEOAS](http://en.wikipedia.org/wiki/HATEOAS);
Qiang Xue committed
12
* Efficient routing with proper HTTP verb check;
Qiang Xue committed
13 14 15
* Built-in support for the `OPTIONS` and `HEAD` verbs;
* Authentication and authorization;
* Data caching and HTTP caching;
16
* Rate limiting;
Qiang Xue committed
17 18


Qiang Xue committed
19 20
In the following, we use an example to illustrate how you can build a set of RESTful APIs with some minimal coding effort.

21
Assume you want to expose the user data via RESTful APIs. The user data are stored in the `user` DB table,
Qiang Xue committed
22 23 24
and you have already created the [[yii\db\ActiveRecord|ActiveRecord]] class `app\models\User` to access the user data.


Qiang Xue committed
25
## Creating a Controller <a name="creating-controller"></a>
Qiang Xue committed
26

Qiang Xue committed
27
First, create a controller class `app\controllers\UserController` as follows,
Qiang Xue committed
28 29 30 31 32 33 34 35

```php
namespace app\controllers;

use yii\rest\ActiveController;

class UserController extends ActiveController
{
Qiang Xue committed
36
    public $modelClass = 'app\models\User';
Qiang Xue committed
37 38 39
}
```

Qiang Xue committed
40 41 42
The controller class extends from [[yii\rest\ActiveController]]. By specifying [[yii\rest\ActiveController::modelClass|modelClass]]
as `app\models\User`, the controller knows what model can be used for fetching and manipulating data.

Qiang Xue committed
43

Qiang Xue committed
44
## Configuring URL Rules <a name="configuring-url-rules"></a>
Qiang Xue committed
45

Qiang Xue committed
46
Then, modify the configuration about the `urlManager` component in your application configuration:
Qiang Xue committed
47 48 49 50 51 52 53

```php
'urlManager' => [
    'enablePrettyUrl' => true,
    'enableStrictParsing' => true,
    'showScriptName' => false,
    'rules' => [
Qiang Xue committed
54
        ['class' => 'yii\rest\UrlRule', 'controller' => 'user'],
Qiang Xue committed
55 56 57 58
    ],
]
```

Qiang Xue committed
59 60 61
The above configuration mainly adds a URL rule for the `user` controller so that the user data
can be accessed and manipulated with pretty URLs and meaningful HTTP verbs.

62

63
## Enabling JSON Input <a name="enabling-json-input"></a>
64

Qiang Xue committed
65
To let the API accept input data in JSON format, configure the [[yii\web\Request::$parsers|parsers]] property of
66 67 68 69 70 71 72 73 74
the `request` application component to use the [[yii\web\JsonParser]] for JSON input:

```php
'request' => [
    'parsers' => [
        'application/json' => 'yii\web\JsonParser',
    ]
]
```
Qiang Xue committed
75

76 77 78 79
> Info: The above configuration is optional. Without the above configuration, the API would only recognize 
  `application/x-www-form-urlencoded` and `multipart/form-data` input formats.


Qiang Xue committed
80
## Trying it Out <a name="trying-it-out"></a>
Qiang Xue committed
81

Qiang Xue committed
82 83 84 85 86 87 88 89 90 91 92 93 94
With the above minimal amount of effort, you have already finished your task of creating the RESTful APIs
for accessing the user data. The APIs you have created include:

* `GET /users`: list all users page by page;
* `HEAD /users`: show the overview information of user listing;
* `POST /users`: create a new user;
* `GET /users/123`: return the details of the user 123;
* `HEAD /users/123`: show the overview information of user 123;
* `PATCH /users/123` and `PUT /users/123`: update the user 123;
* `DELETE /users/123`: delete the user 123;
* `OPTIONS /users`: show the supported verbs regarding endpoint `/users`;
* `OPTIONS /users/123`: show the supported verbs regarding endpoint `/users/123`.

Qiang Xue committed
95
> Info: Yii will automatically pluralize controller names for use in endpoints.
96
> You can configure this using the [[yii\rest\UrlRule::$pluralize]]-property.
Qiang Xue committed
97

Qiang Xue committed
98 99 100
You may access your APIs with the `curl` command like the following,

```
Qiang Xue committed
101
$ curl -i -H "Accept:application/json" "http://localhost/users"
Qiang Xue committed
102 103

HTTP/1.1 200 OK
104
...
Qiang Xue committed
105 106 107 108
X-Pagination-Total-Count: 1000
X-Pagination-Page-Count: 50
X-Pagination-Current-Page: 1
X-Pagination-Per-Page: 20
Qiang Xue committed
109 110 111
Link: <http://localhost/users?page=1>; rel=self, 
      <http://localhost/users?page=2>; rel=next, 
      <http://localhost/users?page=50>; rel=last
Qiang Xue committed
112 113 114
Transfer-Encoding: chunked
Content-Type: application/json; charset=UTF-8

Qiang Xue committed
115 116 117 118 119 120 121 122 123 124 125
[
    {
        "id": 1,
        ...
    },
    {
        "id": 2,
        ...
    },
    ...
]
Qiang Xue committed
126 127 128
```

Try changing the acceptable content type to be `application/xml`, and you will see the result
Qiang Xue committed
129 130 131
is returned in XML format:

```
Qiang Xue committed
132
$ curl -i -H "Accept:application/xml" "http://localhost/users"
Qiang Xue committed
133 134

HTTP/1.1 200 OK
135
...
Qiang Xue committed
136 137 138 139
X-Pagination-Total-Count: 1000
X-Pagination-Page-Count: 50
X-Pagination-Current-Page: 1
X-Pagination-Per-Page: 20
Qiang Xue committed
140 141 142
Link: <http://localhost/users?page=1>; rel=self, 
      <http://localhost/users?page=2>; rel=next, 
      <http://localhost/users?page=50>; rel=last
Qiang Xue committed
143 144 145 146
Transfer-Encoding: chunked
Content-Type: application/xml

<?xml version="1.0" encoding="UTF-8"?>
Qiang Xue committed
147 148 149 150 151 152 153 154 155 156 157
<response>
    <item>
        <id>1</id>
        ...
    </item>
    <item>
        <id>2</id>
        ...
    </item>
    ...
</response>
Qiang Xue committed
158 159
```

160 161 162 163 164 165 166 167 168 169 170 171 172 173
The following command will create a new user by sending a POST request with the user data in JSON format:

```
$ curl -i -H "Accept:application/json" -H "Content-Type:application/json" -XPOST "http://localhost/users" -d '{"username": "example", "email": "user@example.com"}'

HTTP/1.1 201 Created
...
Location: http://localhost/users/1
Content-Length: 99
Content-Type: application/json; charset=UTF-8

{"id":1,"username":"example","email":"user@example.com","created_at":1414674789,"updated_at":1414674789}
```

Qiang Xue committed
174
> Tip: You may also access your APIs via Web browser by entering the URL `http://localhost/users`.
Qiang Xue committed
175
  However, you may need some browser plugins to send specific request headers.
Qiang Xue committed
176 177 178 179 180

As you can see, in the response headers, there are information about the total count, page count, etc.
There are also links that allow you to navigate to other pages of data. For example, `http://localhost/users?page=2`
would give you the next page of the user data.

Qiang Xue committed
181 182
Using the `fields` and `expand` parameters, you may also specify which fields should be included in the result.
For example, the URL `http://localhost/users?fields=id,email` will only return the `id` and `email` fields.
Qiang Xue committed
183 184 185 186


> Info: You may have noticed that the result of `http://localhost/users` includes some sensitive fields,
> such as `password_hash`, `auth_key`. You certainly do not want these to appear in your API result.
Qiang Xue committed
187
> You can and should filter out these fields as described in the [Response Formatting](rest-response-formatting.md) section.
Qiang Xue committed
188 189


Qiang Xue committed
190
## Summary <a name="summary"></a>
Qiang Xue committed
191 192 193 194 195

Using the Yii RESTful API framework, you implement an API endpoint in terms of a controller action, and you use
a controller to organize the actions that implement the endpoints for a single type of resource.

Resources are represented as data models which extend from the [[yii\base\Model]] class.
Qiang Xue committed
196 197
If you are working with databases (relational or NoSQL), it is recommended you use [[yii\db\ActiveRecord|ActiveRecord]]
to represent resources.
Qiang Xue committed
198 199

You may use [[yii\rest\UrlRule]] to simplify the routing to your API endpoints.
Qiang Xue committed
200

Qiang Xue committed
201 202
While not required, it is recommended that you develop your RESTful APIs as a separate application, different from
your Web front end and back end for easier maintenance.