pstaender / silverstripe-restful-api
为 SilverStripe 提供RESTful API助手
Requires
- php: >=5.3.0
This package is auto-updated.
Last update: 2024-09-19 09:27:37 UTC
README
此模块提供了一个基本的API控制器,并带有助手来管理(基于下划线的)JSON数据进行输入/输出。此外,还有一些有助于DataObjects的方法,例如forApi()
。为了验证API控制器,使用SilverStripe构建的安全系统,但提供了一个Auth控制器以RESTful方式验证。
动机
快速轻松地构建API,无需反复编写相同的助手方法。目前处于开发状态,因此某些(设计)决策可能会发生变化,以提供至少令人惊讶的工具。
配置
以下属性可以进行配置
--- Name: RestfulApiConfig --- ApiController: underscoreFields: true useAccesstokenAuth: true accessTokenPropertyName: 'X-Accesstoken' useDataProperty: false AuthSession: validInMinutesFromNow: 10080 adminAccessToken: null requiredGroup: null requiredPermission: null urlSegment: 'auth' ApiSchemaController: allowedModels: - Member DataObject: jsonDateFormat: 'D M d Y H:i:s O' underscoreFields: true castDataObjectFields: true resolveHasOneRelations: true resolveHasManyRelations: true
为了避免在开发期间进行不必要的身份验证,可以使用adminAccessToken
(在开发模式中默认为84c44b7ee63a9919aa272673eecfc7f9b7424e47
)。
如何使用
身份验证
登录
POST:http://localhost/auth/session
,带有(json)正文
{ "email":"your@email.com", "password":"yourpassword" }
返回(状态码200)
{ "session":{ "accesstoken":"8d69f3f127a9ddc4f73d75c5803c846696bb10ff", "valid_until":"Mon Sep 28 2015 03:01:06 +0200", "valid_until_timestamp":1443402066, "user":{ "id":2, … }, "uri":"http://localhost/auth/session/" } }
现在您可以使用accesstoken执行操作。
会话信息
GET:http://localhost/auth/session
,带有头部X-Accesstoken: 8d69f3f127a9ddc4f73d75c5803c846696bb10ff
(您必须始终以这种方式附加Accesstoken以进行身份验证!)返回(状态码200)
{ "session":{ "accesstoken":"8d69f3f127a9ddc4f73d75c5803c846696bb10ff", "valid_until":"Mon Sep 28 2015 03:28:06 +0200", "valid_until_timestamp":1443403686, "user":{ "id":2, … }, "uri":"http://localhost/auth/session/" } }
登出(删除会话)
DELETE:http://localhost/auth/session/8d69f3f127a9ddc4f73d75c5803c846696bb10ff
,带有头部X-Accesstoken: 8d69f3f127a9ddc4f73d75c5803c846696bb10ff
返回(状态码202)
{ "message":"resource deleted successfully" }
在您的项目中使用
您还可以查看这个更详细的示例[https://github.com/pstaender/silverstripe-restful-api/blob/master/code/examples/Country.php]。
数据模型
您可以在模型上应用一些额外的定义,以准备它们用于API使用
class Client extends DataObject { private static $db = [ "Email" => "Varchar", "FirstName" => "Varchar", "Surname" => "Varchar", "Note" => "Text", ]; // these fields be made available by default through `forApi` private static $api_fields = [ "Email", "Name", ]; // example method function Name() { return trim($this->FirstName. " " .$this->Surname); } // can be defined optional function forApi() { $data = parent::forApi(); // will contain s.th. like [ "Email" => "…", "Name" => "…" ] // do s.th. with the data if you want to … return $data; } }
用于模式定义的控制器
为了提供模型合适的模式定义,您可以在config.yml
中显式允许它们
ApiSchemaController: allowedModels: - Country - Member
因此,schema/Member
将显示类似的内容
{ "schema": { "first_name": "Varchar", "surname": "Varchar", "email": "Varchar(256)", "password": "Varchar(160)", "remember_login_token": "Varchar(160)", "num_visit": "Int", "last_visited": "SS_Datetime", "auto_login_hash": "Varchar(160)", "auto_login_expired": "SS_Datetime", "password_encryption": "Varchar(50)", "salt": "Varchar(50)", "password_expiry": "Date", "locked_out_until": "SS_Datetime", "locale": "Varchar(6)", "failed_login_count": "Int", "date_format": "Varchar(30)", "time_format": "Varchar(30)", } }
API 控制器
如何定义自己的API控制器,包括一些方法(我们假设您已将类似"client//$Action/$ID": "ClientController"
添加到您的routes.yml
中)
class ClientController extends APIController { private static $api_parameters = [ "GET:client" => [ '$ID' => "int", ], "POST:client" => [ 'email' => "/^[^@]+@[^@]+$/", ], ]; private static $api_allowed_actions = [ "GET:client" => true, // everyone can read here "DELETE:client" => 'ADMIN', // only admins can delete "POST:client" => '->isBasicApiUser', // method `isBasicApiUser` checks permission ]; private static $api_model = "Client"; // this is to connect this controller to a specific model (important for field matching) /** * Will respond with a JSON object and 200 if found * with a 404 and a JSON msg object otherwise */ function clientGET() { return $this->sendData( Client::get()->byID($this->request->param("ID")) ); } function clientPOST() { $client = Client::create(); $data = $this->requestDataAsArray('Client'); $populateOnlyTheseseFields = [ "Email", "FirstName", "Surname" ]; $country->populateWithData($data, $populateOnlyTheseseFields); $country->write(); return $this->sendSuccesfulPost($country->URL()); } function clientDELETE() { $client = Client::get()->byID($this->request->param("ID"); if (!$client) return $this->sendNotFound(); $client->delete(); return $this->sendSuccessfulDelete(); } protected function isBasicApiUser() { return Permission::check('BASIC_API') || Permission::check('EXTERNAL_API'); } }
有趣的控制器助手
- getAccessTokenFromRequest
- 从头部返回accesstoken
- getSessionFromRequest
- 存在时的会话DataObject
- sendData($data = null, $code = null)
- 发送一个DataList、DataObject或一个数组;默认情况下将被渲染为JSON
- sendJSON($data = null, $code = null)
- 与sendData相同,但强制JSON
- sendError($errMsg, $code = 500)
- 用于向API用户发送可理解的错误消息
- sendNotFound($msg = 'resource not found', $code = 404)
- 发送默认“资源未找到”错误消息的助手
- sendSuccessfulDelete($msg = 'resource deleted successfully', $code = 202)
- 在
DELETE
后发送默认“资源已成功删除”消息的助手
- 在
- sendSuccessfulPut($msg = 'resource updated successfully', $code = 202)
- 在
PUT
后发送默认“资源已成功更新”消息的助手
- 在
- sendSuccessfulPost($uriOrData = null, $msg = 'resource created successfully', $code = 201)
- 如果$uriOrData是一个字符串,则重定向到新资源或发送默认“资源已成功创建”消息的助手
为了简单起见:$msg和$code的参数顺序是任意的。
测试
$ sake dev/tests/module/silverstripe-restful-api flush=1
或
$ sake /dev/tests/AuthControllerTest
运行特定测试。
确保您已定义 $_FILE_TO_URL_MAPPING 在 _ss_environment.php
文件中,以便正确运行控制器测试(否则重定向可能会引发用户错误等)。
更好的性能
通过禁用阻塞会话,您可以减少响应时间。
请注意,在您的 SilverStripe 项目中,请求范围内的会话将不再工作,因为在那种情况下持久化会话存储已被禁用(在纯 RESTful 服务中也不需要)。
要激活此功能,请将以下内容添加到您的 _config.php
或 _ss_environment.php
文件中
define('RESTFUL_API_MODULE_NON_BLOCKING_SESSION', true);
许可证
MIT 许可证