jobbely / phprest
PHP Rest 框架。
Requires
- php: >=5.4.0
- league/booboo: ~1.0.0
- league/container: ~1.1
- league/event: ~2.1
- league/route: ~1.2.3
- monolog/monolog: ~1.12.0
- stack/builder: ~1.0.3
- symfony/console: ~2.8.11
- symfony/http-kernel: ~2.5.12|~2.6.8|~2.7
- willdurand/hateoas: ~2.3.0
- willdurand/negotiation: ~1.3.4
Requires (Dev)
- mockery/mockery: ~0.9.2
- phpunit/phpunit: ~4.2.5
- squizlabs/php_codesniffer: ~2.3.0
Suggests
- phprest/phprest-service-orm: For managing Relational Databases.
- phprest/phprest-service-request-filter: For filtering Entites.
- phprest/phprest-service-validator: For validating Entities.
This package is not auto-updated.
Last update: 2024-10-02 20:05:59 UTC
README
游戏结束
此项目不再维护!
描述
类似 REST 的 PHP 微型框架。
Phprest 仅提供最基础的功能,以构建您自己的架构,并在您喜欢的任何文件夹结构中组装。它只是在一些优秀库的帮助下围绕您的应用程序的一个薄层。
组件
- League\Container
- League\Route
- League\Event
- League\BooBoo
- Willdurand\Negotiation
- Willdurand\Hateoas
- Monolog\Monolog
- Stack\Builder
技能
- 依赖注入
- 路由
- 错误处理
- 序列化
- 反序列化
- HATEOAS
- API 版本控制
- 分页
- 日志记录
目录
安装
通过 composer 安装。
{
"require": {
"phprest/phprest": "@stable"
}
}
提示:您应浏览 phprest/phprest 页面以选择要使用的稳定版本,避免使用 @stable 元约束。
使用
服务
有几个服务可以帮助您解决一些通用问题
这些都是独立的存储库。
设置
<?php require __DIR__ . '/../vendor/autoload.php'; use Phprest\Config; use Phprest\Response; use Phprest\Application; use Symfony\Component\HttpFoundation\Request; # vendor name, current API version, debug $config = new Config('vendor.name', '0.1', true); $app = new Application($config); $app->get('/{version:\d\.\d}/', function (Request $request) { return new Response\Ok('Hello World!'); }); $app->run();
配置
您应检查 Config 类。
日志记录
<?php use Phprest\Service\Logger\Config as LoggerConfig; use Phprest\Service\Logger\Service as LoggerService; use Monolog\Handler\StreamHandler; $config = new Config('vendor.name', '0.1'); $loggerHandlers[] = new StreamHandler('path_to_the_log_file', \Monolog\Logger::DEBUG); $config->setLoggerConfig(new LoggerConfig('phprest', $loggerHandlers)); $config->setLoggerService(new LoggerService());
与 Stack 一起使用
您可以通过 registerMiddleware 函数注册中间件。
$app->registerMiddleware('Jsor\Stack\JWT', [ [ 'firewall' => [ ['path' => '/', 'anonymous' => false], ['path' => '/tokens', 'anonymous' => true] ], 'key_provider' => function() { return 'secret-key'; }, 'realm' => 'The Glowing Territories' ] ]);
API 版本控制
Phprest 默认支持 API 版本。这意味着 ApiVersion 中间件 会处理传入的请求。版本(基于当前 Accept 头)会被添加到路径中。
这意味着什么?
* 它不是一个重定向或转发方法,它只是通过中间件进行的应用内部路由。
API 版本只能是以下范围之一
- 0 - 9
- 0.0 - 9.9
-
如果 Accept 头不可解析
-
那么 Phprest 会抛出 Not Acceptable 异常
-
如果您执行反序列化并且 Content-Type 头不可解析
-
那么 Phprest 会抛出 Unsupported Media Type 异常
路由
有关更多信息,请访问 League/Route。
简单路由
<?php $app->get('/{version:\d\.\d}/hello', function (Request $request, $version) { # You can leave the $request and the $version variable return new Response\Ok('Hello World!'); });
- ApiVersion 中间件 会每次处理内部路由,因此您必须关注路由的第一部分作为版本号。
- 此路由在所有 API 版本中可用(请参阅
\d\.\d正则表达式) - 您还可以设置固定的API版本号,例如:
'/3.6/hello'
带有参数的路由
<?php $app->get('/2.4/hello/{name:word}', function (Request $request, $name) { return new Response\Ok('Hello ' . $name); });
- 此路由仅在API版本2.4中可用
通过控制器进行路由
<?php # index.php # calls index method on HomeController class $app->get('/{version:\d\.\d}/', '\Foo\Bar\HomeController::index');
<?php namespace Foo\Bar; # HomeController.php use Symfony\Component\HttpFoundation\Request; use Phprest\Response; class HomeController { public function index(Request $request, $version) { return new Response\Ok('Hello World!'); } }
通过服务控制器进行路由
<?php $app['HomeController'] = function () { return new \Foo\Bar\HomeController(); }; $app->get('/{version:\d\.\d}/', 'HomeController::index');
使用注解进行路由
您必须注册您的控制器
<?php $app->registerController('\Foo\Bar\Controller\Home');
<?php namespace Foo\Bar\Controller; # Home.php use Phprest\Util\Controller; use Symfony\Component\HttpFoundation\Request; use Phprest\Response; use Phprest\Annotation as Phprest; class Home extends Controller { /** * @Phprest\Route(method="GET", path="/foobars/{id}", since=1.2, until=2.8) */ public function get(Request $request, $version, $id) { return new Response\Ok('Hello World!'); } }
since标签是可选的until标签是可选的
控制器
要创建Phprest控制器,只需将您的类从\Phprest\Util\Controller扩展即可。
<?php namespace App\Module\Controller; class Index extends \Phprest\Util\Controller { public function index(Request $request) { # ... } }
序列化、反序列化、Hateoas
- Phprest将根据Accept头自动序列化您的响应。
- Phprest可以根据Content-Type头反序列化您的内容。
除了*
- 如果您的响应不是Response实例(例如,它是一个简单的字符串)
- 如果您的响应为空
序列化示例
让我们看看一个温度实体
您不必使用注解!您可以使用配置文件!在 Jms\Serializer 和 Willdurand\Hateoas 中浏览
<?php namespace Foo\Entity; use JMS\Serializer\Annotation as Serializer; use Hateoas\Configuration\Annotation as Hateoas; /** * @Serializer\XmlRoot("result") * * @Hateoas\Relation( * "self", * href = @Hateoas\Route("/temperatures", parameters = {"id" = "expr(object.id)"}, absolute = false) * ) */ class Temperature { /** * @var integer * @Serializer\Type("integer") */ public $id; /** * @var integer * @Serializer\Type("integer") */ public $value; /** * @var \DateTime * @Serializer\Type("DateTime") * @Serializer\Since("2") * @Serializer\Exclude */ public $created; /** * @param integer $id * @param integer $value * @param \DateTime $created */ public function __construct($id = null, $value = null, \DateTime $created = null) { $this->id = $id; $this->value = $value; $this->created = $created; } }
路由器
<?php $app->post('/{version:\d\.\d}/temperatures', function () use ($app, $version) { $temperature = new \Foo\Entity\Temperature(1, 32, new \DateTime()); return new Response\Created('/temperatures/1', $temperature); });
Json响应(Accept: application/vnd.vendor+json; version=1)
{
"id": 1,
"value": 32,
"_links": {
"self": {
"href": "\/temperatures\/1"
}
}
}
Xml响应(Accept: application/vnd.vendor+xml; version=1)
<result> <id>1</id> <value>32</value> <link rel="self" href="/temperatures/1"/> </result>
属性将默认从驼峰式转换为下划线小写名称,例如camelCase -> camel_case。如果您想使用自定义序列化名称,必须在您的属性上使用@SerializedName选项。
反序列化示例
您必须在控制器中使用HATEOAS Util特质来进行反序列化。
# ... use JMS\Serializer\Exception\RuntimeException; # ... public function post(Request $request) { try { /** @var \Foo\Entity\Temperature $temperature */ $temperature = $this->deserialize('\Foo\Entity\Temperature', $request); } catch (RuntimeException $e) { throw new Exception\UnprocessableEntity(0, [new Service\Validator\Entity\Error('', $e->getMessage())]); } } # ...
分页
<?php # ... use Hateoas\Representation\PaginatedRepresentation; use Hateoas\Representation\CollectionRepresentation; # ... $paginatedCollection = new PaginatedRepresentation( new CollectionRepresentation([$user1, $user2, ...]), '/users', # route [], # route parameters, should be $request->query->all() 1, # page, should be (int)$request->query->get('page') 10, # limit, should be (int)$request->query->get('limit') 5, # total pages 'page', # page route parameter name, optional, defaults to 'page' 'limit', # limit route parameter name, optional, defaults to 'limit' true, # absolute URIs 47 # total number of rows ); # ... return new Response\Ok($paginatedCollection);
有关更多信息,请访问HATEOAS文档
响应
默认情况下,您可以使用几种响应,其中之一是Ok响应。
1xx、2xx、3xx 状态码
这些都是简单的Response对象。
示例
<?php # ... $app->get('/', function (Request $request) { return new Response\Ok('Hello World!'); }); # ...
类型
4xx、5xx 状态码
这些都是异常。
示例
<?php # ... $app->get('/', function (Request $request) { # ... throw new \Phprest\Exception\BadRequest(); # ... }); # ...
类型
依赖注入容器
请参阅Proton的文档,以及更多信息的League/Container。
命令行界面
如果您想在composer安装后使用,可以使用辅助脚本(vendor/bin/phprest)。
您必须提供(引导的)应用程序实例给脚本。您有两个选择
- 将您的应用程序实例放入特定文件:
app/app.php - 您必须在适当的文件中返回引导的应用程序实例
- 将应用程序实例的路径放入
paths.php文件中 - 您必须从
paths.php文件返回一个数组,其中包含在app数组键下的应用程序文件路径
错误处理器
Phprest使用League\BooBoo来处理错误。默认格式化器是Json和Xml格式化器。
单个异常
<?php # ... $app->get('/{version:\d\.\d}/', function (Request $request, $version) { throw new \Phprest\Exception\Exception('Code Red!', 9, 503); }); # ...
响应进行内容协商(xml/json),状态码为503。
{
"code": 9,
"message": "Code Red!",
"details": []
}
<result> <code>9</code> <message> <![CDATA[Code Red!]]> </message> </result>
身份验证
基本身份验证
您将需要此包
$app->registerMiddleware('Dflydev\Stack\BasicAuthentication', [ [ 'firewall' => [ ['path' => '/', 'anonymous' => false], ['path' => '/temperatures', 'method' => 'GET', 'anonymous' => true] ], 'authenticator' => function ($username, $password) { if ('admin' === $username && 'admin' === $password) { # Basic YWRtaW46YWRtaW4= return 'success'; } }, 'realm' => 'The Glowing Territories' ] ]);
JWT 身份验证
您将需要此包
$app->registerMiddleware('Jsor\Stack\JWT', [ [ 'firewall' => [ ['path' => '/', 'anonymous' => false], ['path' => '/tokens', 'anonymous' => true] ], 'key_provider' => function() { return 'secret-key'; }, 'realm' => 'The Glowing Territories' ] ]);
API 测试
有一些非常好的工具可用于测试您的API。
- Postman 和 Newman
- 提示:在Postman中创建集合,然后在Newman中运行这些操作
- Frisby
- Frisby是一个基于node.js和Jasmine构建的REST API测试框架,它使测试API端点变得简单、快速且有趣。
- Runscope
- 用于API监控和测试
API 文档
仅提供一些建议
- API Blueprint
- API Blueprint是一种面向文档的API描述语言。它对纯Markdown进行了一些语义假设。
- Swagger
- 使用Swagger启用的API,您将获得交互式文档、客户端SDK生成和可发现性。