tbbc/rest-util-bundle 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

tbbc/rest-util-bundle

最新稳定版本:v1.0.3

Composer 安装命令:

composer require tbbc/rest-util-bundle

包简介

Bundle for integrating tbbc/rest-util lib in a Symfony application.

README 文档

README

Build Status Scrutinizer Quality Score

A bundle for integrating tbbc/rest-util lib in a Symfony application

Table of contents

  1. Installation
  2. Quick start
  3. Usage
  4. Run the test
  5. Contributing
  6. Requirements
  7. Authors
  8. License

Installation

Using Composer, just $ composer require tbbc/rest-util-bundle package or:

{ "require": { "tbbc/rest-util-bundle": "@stable" } }

Quick start

Handling errors in a REST(ful) API

#### Configuration

tbbc_rest_util: error: use_bundled_factories: true exception_mapping: FormErrorException: class: "Tbbc\\RestUtilBundle\\Error\\Exception\\FormErrorException" factory: tbbc_rest_util_form_error http_status_code: 400 error_code: 400101 error_message: "Invalid input" error_more_info_url: "http://api.my.tld/doc/error/400101" AccessDeniedException: class: "Symfony\\Component\\Security\\Core\\AccessDeniedException" factory: default http_status_code: 401 error_code: 401001 error_message: "Access denied" extended_message: "The given token don't have enough privileges for accessing to this resource" error_more_info_url: "http://api.my.tld/doc/error/401001" CustomException: class: "My\\ApiBundle\\Exception\\CustomException" factory: my_api_custom http_status_code: 501 error_code: 501001 error_more_info_url: "http://api.my.tld/doc/error/501001" Exception: class: "\\Exception" factory: default http_status_code: 500 error_code: 501203 error_message: "Server error"

Custom Symfony Exception Listener

<?php namespace My\ApiBundle\EventListener; // ... other use statements use Tbbc\RestUtil\Error\ErrorResolverInterface; class RestExceptionListener extends ExceptionListener { private $errorResolver; public function __construct(ErrorResolverInterface $errorResolver, $controller, LoggerInterface $logger = null) { $this->errorResolver = $errorResolver; parent::__construct($controller, $logger); } /**  * @param GetResponseForExceptionEvent $event  * @return void  */ public function onKernelException(GetResponseForExceptionEvent $event) { static $handling; if (true === $handling) { return; } $exception = $event->getException(); $error = $this->errorResolver->resolve($exception); if (null == $error) { return; } $handling = true; $response = new Response(json_encode($error->toArray()), $error->getHttpStatusCode(), array( 'Content-Type' => 'application/json' )); $event->setResponse($response); } public static function getSubscribedEvents() { return array( KernelEvents::EXCEPTION => array('onKernelException', 10), ); } }
<?xml version="1.0" ?> <container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> <parameters> <parameter key="my_api.event_listener.rest_exception.class">My\ApiBundle\EventListener\RestExceptionListener</parameter> </parameters> <services> <service id="my_api.event_listener.rest_exception" class="%my_api.event_listener.rest_exception.class%"> <tag name="kernel.event_subscriber" /> <tag name="monolog.logger" channel="request" /> <argument type="service" id="tbbc_rest_util.error.error_resolver" /> <argument>%twig.exception_listener.controller%</argument> <argument type="service" id="logger" on-invalid="null" /> </service> </services> </container>

Api Controller code

<?php namespace My\ApiBundle\Controller; // ... other use statements use Symfony\Component\Security\Core\AccessDeniedException; use Tbbc\RestUtilBundle\Error\Exception\FormErrorException; use My\ApiBundle\Exception\CustomException; class PostCommentsController extends Controller { public function postCommentsAction($postId) { // ... fetch $post with $postId if (!$this->get('security.context')->isGranted('COMMENT', $post)) { throw new AccessDeniedException('Access denied'); } $commentResource = new CommentResource(); $form = $this->createNamedForm('', new CommentResourceType(), $commentResource); $form->bind($this->getRequest()); if (!$form->isValid()) { throw new FormErrorException($form); } // another error if (....) { throw new CustomException('Something bad just happened!'); } // ... save comment or whatever } }

MyApiCustomException error factory

<?php namespace My\ApiBundle\Error\Factory; use Tbbc\RestUtil\Error\Error; use Tbbc\RestUtil\Error\ErrorFactoryInterface; use Tbbc\RestUtil\Error\Mapping\ExceptionMappingInterface; use My\ApiBundle\Exception\CustomException; class CustomErrorFactory implements ErrorFactoryInterface { /**  * {@inheritDoc}  */ public function getIdentifier() { return 'my_api_custom'; } /**  * {@inheritDoc}  */ public function createError(\Exception $exception, ExceptionMappingInterface $mapping) { if (!$this->supportsException($exception)) { return null; } $errorMessage = $mapping->getErrorMessage(); if (empty($errorMessage)) { $errorMessage = $exception->getMessage(); } $extendedMessage = $exception->getMoreExtendedMessage(); // Or whatever you need to do with your exception here return new Error($mapping->getHttpStatusCode(), $mapping->getErrorCode(), $errorMessage, $extendedMessage, $mapping->getErrorMoreInfoUrl()); } /**  * {@inheritDoc}  */ public function supportsException(\Exception $exception) { return $exception instanceof CustomException; } }
<?xml version="1.0" ?> <container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> <parameters> <parameter key="my_api.error.custom_error_factory.class">My\ApiBundle\Error\Factory\CustomErrorFactory</parameter> </parameters> <services> <service id="my_api.error.custom_error_factory" class="%my_api.error.custom_error_factory.class%"> <tag name="tbbc_rest_util.error_factory" /> </service> </services> </container>

ENJOY!

For the exceptions thrown in the previous PostCommentsController class example, the response body will be respectively something like the following:

For the AccessDeniedException exception:

{ "http_status_code": 401, "code": 401001, "message": "Access denied", "extended_message": "The given token don't have enough privileges for accessing to this resource", "more_info_url": "http:\/\/api.my.tld\/doc\/error\/401001" }

For the FormErrorException exception:

{ "http_status_code": 400, "code": 400101, "message": "Invalid input", "extended_message": { "global_errors": [ "Bubbled form error!" ], "property_errors": { "content": [ "The comment content should not be blank", ] } }, "more_info_url": "http:\/\/api.my.tld\/doc\/error\/400101" }

For the CustomException exception:

{ "http_status_code": 501, "code": 501001, "message": "Something bad just happened!", "extended_message": null, "more_info_url": "http:\/\/api.my.tld\/doc\/error\/501001" }

Usage

Run the test

First make sure you have installed all the dependencies, run:

$ composer install --dev

then, run the test from within the root directory:

$ vendor/bin/phpunit

Contributing

  1. Take a look at the list of issues.
  2. Fork
  3. Write a test (for either new feature or bug)
  4. Make a PR

Requirements

  • PHP 5.3+

Authors

License

The Big Brains Company - TbbcRestUtilBundle is licensed under the MIT License - see the LICENSE file for details

The Big Brains Company - Logo

统计信息

  • 总下载量: 203.52k
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 30
  • 点击次数: 1
  • 依赖项目数: 1
  • 推荐数: 0

GitHub 信息

  • Stars: 30
  • Watchers: 6
  • Forks: 6
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-01-04

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固