osm/easy-rest-bundle
Composer 安装命令:
composer require osm/easy-rest-bundle
包简介
Simple and lightweight bundle provides JSON based request / response and exception handling support to develop RESTful API's with Symfony.
README 文档
README
Simple and lightweight bundle provides JSON based request / response and exception handling support to develop RESTful API's with Symfony.
Features include:
- Listener for decoding JSON request body and accessing it from Request class
ParamConverterfor mapping JSON request to plain PHP object (using Symfony Serializer)- (New in 1.3.0) Supports nested objects and arrays using PHPDoc hints
- Listener for creating JSON responses which is converts to JSON
- Automatically determines correct HTTP status codes for DELETE and POST response
- Exception controller for providing error details
- Supports Symfony Validation errors
- Provides stack-trace on development environment
- Supports Symfony 2 and 3
- Only uses plain listeners, easy to configure and disable certain features.
Not supports:
- XML serializer or format agnostic helpers
- Header format negotiation
Installation
Step 1: Download the Bundle
Open a command console, enter your project directory and execute the following command to download the latest stable version of this bundle:
$ composer require osm/easy-rest-bundle "~1"
This command requires you to have Composer installed globally, as explained in the installation chapter of the Composer documentation.
Step 2: Enable the Bundle
Then, enable the bundle by adding it to the list of registered bundles
in the app/AppKernel.php file of your project:
<?php
// app/AppKernel.php
// ...
class AppKernel extends Kernel
{
public function registerBundles()
{
$bundles = array(
// ...
new Osm\EasyRestBundle\OsmEasyRestBundle(),
);
// ...
}
// ...
}
Step 3: Configuration
Enable the bundle's configuration in app/config/config.yml:
osm_easy_rest: ~
With default configuration, all listeners and exception controller will be enabled. You can change this behaviour with following options:
osm_easy_rest:
enable_exception_listener: true
enable_json_param_converter: false
enable_json_response_listener: true
enable_request_body_listener: true
Usage
JSON Request and Response
Response
Responses are handled by JsonResponseListener listener. It's directly uses Symfony JsonResponse class for creating response. Simply you can use arrays or JsonSerializable objects.
GET request and response:
curl -i localhost:8000/v1/users/12/details
Controller
/**
* @Method({"GET"})
* @Route("/v1/users/12/details")
*/
public function getUserDetailsSample()
{
return [
'user' => [
'id' => '8f262cd7-9f2d-4bca-825e-e2444b1a57e0',
'username' => 'o',
'isEnabled' => true,
'roles' => [
'ROLE_USER',
'ROLE_ADMIN'
]
]
];
}
Response will be,
HTTP/1.1 200 OK
Cache-Control: no-cache, private
Connection: close
Content-Type: application/json
{
"user": {
"id": "8f262cd7-9f2d-4bca-825e-e2444b1a57e0",
"isEnabled": true,
"roles": [
"ROLE_USER",
"ROLE_ADMIN"
],
"username": "o"
}
}
Request
Requests are handled by RequestContentListener, it tries to convert request body to array and wraps in ParameterBag. It's only activated for POST, PUT and PATCH requests. So, you can access to this parameters from Symfony Request object.
POST request example with JSON body:
curl -i -X POST \
http://localhost:8000/access-tokens \
-H 'content-type: application/json' \
-d '{
"username": "o",
"password": "t0o53cur#",
}'
In controller you can access parameters like:
/**
* @Method({"POST"})
* @Route("/access-tokens")
*/
public function createTokenAction(Request $request) {
$username = $request->request->get('username'); // Will produce 'o'
$password = $request->request->get('password'); // Will produce 't0o53cur#'
....
}
Json Param Converter
You can also use PHP objects for mapping and validating request. Your request object should implement JsonRequestInterface interface.
use Osm\EasyRestBundle\ParamConverter\JsonRequestInterface;
use Symfony\Component\Validator\Constraints as Assert;
class CreateTokenRequest implements JsonRequestInterface
{
/**
* @Assert\NotBlank()
*/
private $username;
/**
* @Assert\NotBlank()
* @Assert\Regex("/(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[\W])/", message="Your password should contain a digit, a lowercase, an uppercase and a special character.")
* @Assert\Length(min="8")
*/
private $password;
// Getter / setters removed for brevity
}
Accessing and validating from controller:
POST request example with JSON body:
curl -i -X POST \
http://localhost:8000/access-tokens \
-H 'content-type: application/json' \
-d '{
"username": "o",
"password": "t0o53cur#",
}'
A param converter directly unmarshalls JSON request to your object.
/**
* @Route()
* @Method("POST")
* @throws ValidationException
*/
public function createTokenAction(CreateTokenRequest $createTokenRequest, ValidatorInterface $validator)
{
$errors = $validator->validate($createTokenRequest);
if (count($errors)) {
throw new ValidationException($errors);
}
$createTokenRequest->getUsername(); // Will produce 'o'
$createTokenRequest->getPassword(); // Will produce 't0o53cur#'
}
Working with exceptions and validation errors
In default, an exception controller also converts handled exceptions to strict signature JSON responses with respective HTTP status codes.
/**
* @Route("/test/precondition-failed")
*/
public function testPreconditionFailed(Request $request) {
...
if (!$hasRequirements) {
throw new PreconditionFailedHttpException('Invalid condition');
}
}
Response will be:
$ curl -i localhost:8000/test/precondition-failed
HTTP/1.1 412 Precondition Failed
Cache-Control: no-cache, private
Connection: close
Content-Type: application/json
{
"code": 0,
"errors": [],
"message": "Invalid condition",
"status_code": 412,
"status_text": "Precondition Failed",
"trace": []
}
In the development mode for the unhandled exceptions also a stack-trace is included in response.
Validation errors and ExceptionWrapper
For exceptions, this bundle comes with ExceptionWrapper for creating error responses in a nice way.
Using with Symfony Validator errors:
/**
* @Method({"POST"})
* @Route("/access-tokens")
*/
public function createTokenAction(Request $request) {
....
$errors = $this->get('validator')->validate(
$request->request->all(),
new Assert\Collection(
[
'username' => [
new Assert\NotBlank(),
],
'password' => [
new Assert\NotBlank(),
new Assert\Length(['min' => 5]),
],
]
)
);
return (new ExceptionWrapper())
->setErrorsFromConstraintViolations($errors)
->setMessage(ErrorMessagesInterface::VALIDATION_ERROR)
->setStatusCode(Response::HTTP_UNPROCESSABLE_ENTITY)
->getResponse();
}
An example request which is we expect to fail:
curl -i -X POST \
http://localhost:8000/access-tokens \
-H 'content-type: application/json' \
-d '{
"username": "",
"password": "t0o53cur#",
"extra_field": false
}'
Response will be:
HTTP/1.1 422 Unprocessable Entity
Cache-Control: no-cache, private
Connection: close
Content-Type: application/json
{
"code": 0,
"errors": [
{
"message": "This value should not be blank.",
"path": "username"
},
{
"message": "This field was not expected.",
"path": "extra_field"
}
],
"message": "Validation Failed",
"status_code": 422,
"status_text": "Unprocessable Entity",
"trace": []
}
You can also build your own custom error details:
/**
* @Route("/test/weird-error-test")
*/
public function getWeirdErrors()
{
return (new ExceptionWrapper())
->setMessage('Something going wrong')
->setStatusCode(Response::HTTP_I_AM_A_TEAPOT)
->addError('foo', 'I don\'t expect an input like this')
->addError('bar', 'This should be an integer')
->getResponse();
}
You will expect a response with this structure
curl -i localhost:8000/test/weird-error-test
HTTP/1.1 418 I'm a teapot
Cache-Control: no-cache, private
Connection: close
Content-Type: application/json
{
"code": 0,
"errors": [
{
"message": "I don't expect an input like this",
"path": "foo"
},
{
"message": "This should be an integer",
"path": "bar"
}
],
"message": "Something going wrong",
"status_code": 418,
"status_text": "I'm a teapot",
"trace": []
}
License
This bundle is distributed under the MIT license. Copyright (c) 2015-2018 Osman Ungur
osm/easy-rest-bundle 适用场景与选型建议
osm/easy-rest-bundle 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 1.45k 次下载、GitHub Stars 达 9, 最近一次更新时间为 2015 年 11 月 16 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「json」 「rest」 「rest-api」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 osm/easy-rest-bundle 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 osm/easy-rest-bundle 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 osm/easy-rest-bundle 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Kinikit - PHP Application development framework MVC component
Provided middleware for generating of swagger-documentation file by run testing of restful API.
ext-json wrapper with sane defaults
A package to cast json fields, each sub-keys is castable
A PSR-7 compatible library for making CRUD API endpoints
Api bundle
统计信息
- 总下载量: 1.45k
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 9
- 点击次数: 3
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2015-11-16