阿江 2017-10-15 08:23:21 4090次浏览 0条回复 2 0 0

说明

学习Yii Framework 2易2框架的过程是漫长的也是充满乐趣的以下是我学习Yii2框架时对官网英文资料(请参见原文网址)的翻译和代码实现提供了较完整的代码供你参考不妥之处请多多指正

原文网址:

http://www.yiiframework.com/doc-2.0/guide-rest-quick-start.html

本文主题:RESTful快速上手(Quick Start)

Yii提供了一整套的开发工具用于简化RESTful Web Service API的开发过程,实际上,Yii的RESTful API具有如下特征: 1、针对Active Record的快速原型支持通用API 2、响应格式协商确定(默认支持JSON和XML格式) 3、可自定义的对象序列化,可以只输出选定的字段 4、数据集和验证错误信息的格式化 5、支持HATEOAS(Hypermedia As The Engine Of Application State) 6、有效的路由与适当的HTTP动词检查 7、内置OPTIONS和HEAD动词支持 8、验证和授权 9、数据缓存和HTTP缓存 10、请求频率限制

接下来,我们将使用一个例子向你展示如何使用极少的代码就可以构建一套RESTful接口。 假定你需要使用RESTful API处理你的用户数据,用户数据保存在数据表user中,你已经创建了Active Record类app\models\User用于获取用户数据。

1、Creating a Controller(创建一个控制器)

首先创建一个控制器类frontend\controllers\UserController,代码如下: D:\phpwork\advanced\frontend\controllers\UserController.php

<?php
namespace frontend\controllers;
use yii\rest\ActiveController;
class UserController extends ActiveController
{
    public $modelClass = 'frontend\models\User';
}

控制器类继承自yii\rest\ActiveController,此类已实现了一组RESTful的通用动作。通过将modelClass定义为app\models\User,控制器知道使用哪个模型来获取和处理数据。

2、Configuring URL Rules(配置URL规则)

接下来在应用配置中修改urlManager组件: D:\phpwork\advanced\frontend\config\main.php

'urlManager' => [
    'enablePrettyUrl' => true,
    'enableStrictParsing' => true,
    'showScriptName' => false,
    'rules' => [
		[
			'class' => 'yii\rest\UrlRule',
			'controller' => 'user',
			//默认使用http://localhost:8082/users访问
			//'pluralize'=>false,//加上此句后,使用http://localhost:8082/user可访问,而不是http://localhost:8082/users
		],
    ],
]

上述配置主要是为user控制器添加了一个URL规则,这样可以使用简洁URL(pretty URL)和有意义的HTTP动词来获取和处理用户数据。

注意:Yii自动将控制器名称变为复数形式(请参考后面的Trying it Out章节),你可以使用yii\rest\UrlRule::$pluralize 属性来配置它。

3、Enabling JSON Input(使JSON输入生效)很重要!!

要使API接受JSON格式的数据输入,需要配置request应用组件的parsers属性使用yii\web\JsonParser: \yiibasic\config\web.php

'components' => [
	'request' => [
		'parsers' => [
			'application/json' => 'yii\web\JsonParser',
		],
		......
	],
	......
],

信息:上述配置是可选项,如果没有配置,则API将只识别application/x-www-form-urlencoded和multipart/form-data格式的输入。

4、Trying it Out(尝试输出)

使用上述的最小化代码配置,你已经完成了获取用户数据的RESTful API创建工作,在此API中,你已创建了以下动作: GET /users: 一页一页的列出所有用户 HEAD /users: 显示用户列表的概览信息 POST /users: 创建一个新用户 GET /users/123: 返回用户123的详细信息 HEAD /users/123: 显示用户123的概览信息 PATCH /users/123: 更新用户123的信息(局部字段更新) PUT /users/123: 更新用户123的信息(全部更新) DELETE /users/123: 删除用户123 OPTIONS /users: 显示/users支持的动词 OPTIONS /users/123: 显示/users/123支持的动词

你可以使用curl命令获取你的API,代码如下:

$ curl -i -H "Accept:application/json" "http://localhost/users"

HTTP/1.1 200 OK
...
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,
        ...
    },
    ...
]

如果要改变接收的数据类型为application/xml,你将看到返回的XML格式的结果:

$ curl -i -H "Accept:application/xml" "http://localhost/users"

HTTP/1.1 200 OK
...
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/xml

<?xml version="1.0" encoding="UTF-8"?>
<response>
    <item>
        <id>1</id>
        ...
    </item>
    <item>
        <id>2</id>
        ...
    </item>
    ...
</response>

以下命令将发送一个POST请求以创建一个新用户,数据以JSON格式提供:

$ 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}

小贴士:你也可以使用Web浏览器输入URL http://localhost/users 来访问你的API,另外,你还需要一些浏览器插件来发送特定的请求头信息。

如你所见,响应的头信息中包含:总数,页数等,也有一些访问其他页数据的链接。例如,http://localhost/users?page=2 将提供访问用户数据下一页的链接。 使用fields和expand参数,你也定义将要包含在结果中的字段,例如,http://localhost/users?fields=id,email将仅返回id和email两个字段。

信息:你需要注意的是http://localhost/users中包含一些敏感字段,如password_hash, auth_key等,不能让这些信息出现在API的结果中,你可以如Resources章节描述的一样,将这些字段过滤掉。 Resources章节: http://www.yiiframework.com/doc-2.0/guide-rest-resources.html

实例,使用curl访问(在Git Bash命令窗口内):
$ curl -i -H "Accept:application/json" "http://localhost:8082/user/5"
/*
HTTP/1.1 200 OK
Date: Mon, 08 May 2017 08:24:45 GMT
Server: Apache/2.4.20 (Win64) OpenSSL/1.0.2g PHP/5.6.20
X-Powered-By: PHP/5.6.20
Content-Length: 333
Content-Type: application/json; charset=UTF-8

{"id":5,"username":"oakala","email":"allaa@163.net","createdAt":1461664500,"upda
ted_at":1473762490,"status":4,"_links":{"self":{"href":"http://localhost:8082/us
er/5"},"edit":{"href":"http://localhost:8082/user/5"},"profile":{"href":"http://
localhost:8082/user/profile/view?id=5"},"index":{"href":"http://localhost:8082/u
ser/users"}}}
*/
User@User-PC MINGW32 /d/phpwork/b2b/imall (ycjnx)
$

//接收格式为xml
$ curl -i -H "Accept:application/xml" "http://localhost:8082/user/5"
//与上句等效:
$ curl -i -H "Accept:application/xml" "http://localhost:8082/user/5" -XGET
/*
HTTP/1.1 200 OK
Date: Mon, 08 May 2017 08:30:55 GMT
Server: Apache/2.4.20 (Win64) OpenSSL/1.0.2g PHP/5.6.20
X-Powered-By: PHP/5.6.20
Content-Length: 473
Content-Type: application/xml; charset=UTF-8

<?xml version="1.0" encoding="UTF-8"?>
<response><id>5</id><username>oakala</username><email>allaa@163.net</email><crea
tedAt>1461664500</createdAt><updated_at>1473762490</updated_at><status>4</status
><_links><self><href>http://localhost:8082/user/5</href></self><edit><href>http:
//localhost:8082/user/5</href></edit><profile><href>http://localhost:8082/user/p
rofile/view?id=5</href></profile><index><href>http://localhost:8082/user/users</
href></index></_links></response>
*/
User@User-PC MINGW32 /d/phpwork/b2b/imall (ycjnx)
$

//使用POST方式提交json数据报错:应用配置components->request->parsers未定义
//已定义的username字段仍然显示了出错信息
$ curl -i -H "Accept:application/json" -H "Content-Type:application/json" XPOST
 "http://localhost:8086/users" -d '{"username":"example","email":"user@example.
com"}'
/*
curl: (6) Couldn't resolve host 'XPOST'
HTTP/1.1 422 Data Validation Failed.
Date: Mon, 15 May 2017 08:03:54 GMT
Server: Apache/2.4.20 (Win64) OpenSSL/1.0.2g PHP/5.6.20
X-Powered-By: PHP/5.6.20
Content-Length: 367
Content-Type: application/json; charset=UTF-8

[{"field":"username","message":"Username cannot be blank."},{"field":"auth_key",
"message":"Auth Key cannot be blank."},{"field":"password_hash","message":"Passw
ord Hash cannot be blank."},{"field":"email","message":"Email cannot be blank."}
,{"field":"created_at","message":"Created At cannot be blank."},{"field":"update
d_at","message":"Updated At cannot be blank."}]
*/
User@User-PC MINGW32 /d/phpwork/b2b/imall (ycjnx)
$

//使用POST方式提交json数据,以创建一条记录,报错:验证信息未通过
$ curl -i -H "Content-Type:application/json" -XPOST "http://localhost:8082/user
" -d '{"username":"abc123","email":"alabc@163.com"}'
/*
HTTP/1.1 422 Data Validation Failed.
Date: Mon, 08 May 2017 08:47:10 GMT
Server: Apache/2.4.20 (Win64) OpenSSL/1.0.2g PHP/5.6.20
X-Powered-By: PHP/5.6.20
Content-Length: 255
Content-Type: application/json; charset=UTF-8
[{"field":"auth_key","message":"Auth Key cannot be blank."},{"field":"password_h
ash","message":"Password Hash cannot be blank."},{"field":"created_at","message"
:"Created At cannot be blank."},{"field":"updated_at","message":"Updated At cann
ot be blank."}]
*/
User@User-PC MINGW32 /d/phpwork/b2b/imall (ycjnx)
$

//在表user中成功创建一条数据(不用进行身份验证!)json数据两边必须使用单引号括起来
$ curl -i -H "Content-Type:application/json" -XPOST "http://localhost:8082/user" -d '{"username":"abc123","email":"alabc@163.com","auth_key":"38j9ISlh85aYMI7M3-aMPNBB-E46VIIX","password_hash":"sWtikd9ooVETqI4uQMXV.PsJGsUqTBE0yzotNY1QWaVWohmE3gZq","created_at":"1461664500","updated_at":"1473762490"}'
HTTP/1.1 201 Created
Date: Mon, 08 May 2017 08:54:07 GMT
Server: Apache/2.4.20 (Win64) OpenSSL/1.0.2g PHP/5.6.20
X-Powered-By: PHP/5.6.20
Location: http://localhost:8082/user/9
Content-Length: 340
Content-Type: application/json; charset=UTF-8

{"id":9,"username":"abc123","email":"alabc@163.com","createdAt":"1461664500","up
dated_at":"1473762490","status":null,"_links":{"self":{"href":"http://localhost:
8082/user/9"},"edit":{"href":"http://localhost:8082/user/9"},"profile":{"href":"
http://localhost:8082/user/profile/view?id=9"},"index":{"href":"http://localhost
:8082/user/users"}}}
User@User-PC MINGW32 /d/phpwork/b2b/imall (ycjnx)
$

//运行数据插入命令,出错,一屏信息看不全,则是user控制器不存在,应为users
$ curl -i -H "Content-Type:application/json" -XPOST "http://localhost:8086/user" -d '{"username":"abc123","email":"alabc@163.com","auth_key":"38j9ISlh85aYMI7M3-aMPNBB-E46VIIX","password_hash":"sWtikd9ooVETqI4uQMXV.PsJGsUqTBE0yzotNY1QWaVWohmE3gZq","created_at":"1461664500","updated_at":"1473762490"}'
            requestStack.push(stackElement);
            this.addEventListener("readystatechange", function () {
                if (self.readyState == 4) {
                    stackElement.duration = self.getResponseHeader("X-Debug-Dura
tion") || new Date() - stackElement.start;
                    stackElement.loading = false;
                    stackElement.statusCode = self.status;
                    stackElement.error = self.status < 200 || self.status >= 400
;
                    stackElement.profile = self.getResponseHeader("X-Debug-Tag")
;
                    stackElement.profilerUrl = self.getResponseHeader("X-Debug-L
ink");
                    renderAjaxRequests();
                }
            }, false);
            renderAjaxRequests();
        }
        proxied.apply(this, Array.prototype.slice.call(arguments));
    };

})();</script><script src="/assets/29ffdff6/jquery.js"></script>
<script src="/assets/d3c40c12/yii.js"></script>
<script src="/assets/907a3baa/js/bootstrap.js"></script></body>
</html>

User@User-PC MINGW32 /d/phpwork/b2b/imall (ycjnx)
$

//查看options
$ curl -i -H "Accept:application/xml" "http://localhost:8082/user/5" -XOPTIONS
HTTP/1.1 405 Method Not Allowed
Date: Thu, 11 May 2017 09:30:41 GMT
Server: Apache/2.4.20 (Win64) OpenSSL/1.0.2g PHP/5.6.20
X-Powered-By: PHP/5.6.20
Allow: GET, HEAD
Content-Length: 281
Content-Type: application/xml; charset=UTF-8

<?xml version="1.0" encoding="UTF-8"?>
<response><name>Method Not Allowed</name><message>Method Not Allowed. This url c
an only handle the following request methods: GET, HEAD.</message><code>0</code>
<status>405</status><type>yii\web\MethodNotAllowedHttpException</type></response
>

User@User-PC MINGW32 /d/phpwork/b2b/imall (ycjnx)
$

<?
//查看options
$ curl -i -H "Accept:application/xml" "http://localhost:8082/user" -XOPTIONS
HTTP/1.1 200 OK
Date: Thu, 11 May 2017 09:31:37 GMT
Server: Apache/2.4.20 (Win64) OpenSSL/1.0.2g PHP/5.6.20
X-Powered-By: PHP/5.6.20
Allow: GET, POST, HEAD, OPTIONS
Content-Length: 0
Content-Type: application/xml; charset=UTF-8

User@User-PC MINGW32 /d/phpwork/b2b/imall (ycjnx)
$

$ curl -i "http://localhost:8082/user" -XOPTIONS
HTTP/1.1 200 OK
Date: Thu, 11 May 2017 09:33:48 GMT
Server: Apache/2.4.20 (Win64) OpenSSL/1.0.2g PHP/5.6.20
X-Powered-By: PHP/5.6.20
Allow: GET, POST, HEAD, OPTIONS
Content-Length: 0
Content-Type: application/json; charset=UTF-8

User@User-PC MINGW32 /d/phpwork/b2b/imall (ycjnx)
$
5、Summary(总结)

使用Yii的RESTful API框架,你可以使用控制器/动作模式实现API,你可以使用一个控制器来组织动作实现单一类型资源的端点。

数据模型代表了资源,它扩展自yii\base\Model类,如果你要操作数据库,最好使用ActiveRecord来代表资源。

你可以使用yii\rest\UrlRule来简化API端点的路由。

作为推荐(非必须的)你应使用独立应用来开发你的RESTful API,由此与网站的前端和后端分开,便于维护。

Yii2 RESTful Web Service Quick Start的完整实例请参见:

http://www.yiichina.com/topic/6905

(全文完)

    没有找到数据。
您需要登录后才可以回复。登录 | 立即注册