bentools/api-first-bundle

此包已弃用且不再维护。未建议替代包。

为使用Symfony进行API优先设计的项目提供类。

安装: 94

依赖项: 0

建议者: 0

安全: 0

星标: 0

关注者: 1

分支: 0

开放问题: 0

类型:symfony-bundle

v0.6.2 2016-08-23 12:56 UTC

README

为使用Symfony进行API优先设计的项目提供类。

目前仅供个人使用。

此包的目的是帮助设计可以同时使用API和UI的Symfony应用程序。

概念

Symfony实体是一个具有id的资源。它应该实现ResourceInterface接口,该接口仅要求实现一个getId()方法。

几个类与这个资源进行交互

  • ORM / ODM类(EntityManager,Repository)
  • 表单类
  • 操作类(GET,POST,PUT,PATCH,DELETE,相关资源等)

AbstractResourceHandler是一个服务,它提供了对特定资源的相应类的访问。

以下是流程

  • AbstractResourceHandler提供表单处理。它是HTTP无关的:您可以从Request或原始数据(数组)提交表单。您可以在cron作业、批量操作中使用它,它的角色不是发送Response,而是发送Resource。当表单失败时,它抛出ValidationFormException
  • 操作类调用AbstractResourceHandler来转换一个带有RequestResource
  • 操作类可以生成预响应,在其中它们可以定义
    • 在成功时做什么(重定向到URL,添加flashes等,如果是UI请求)
    • 回复哪个HTTP状态码(如果是API提交)
  • 事件监听器将这个PreResponse转换成正确的响应,带有内容协商(如果是来自UI的请求,则重定向+flash;如果是API请求,则状态码)
  • AbstractResourceHandler抛出ValidationFormException时,操作类应该
    • 在UI请求的情况下,返回带有表单和错误的HTTP 200响应代码
    • 在API请求的情况下,返回带有序列化表单错误的HTTP 400响应代码
    • BenTools\ApiFirstBundle\Model\AbstractCRUDAction::submitForm()方法在成功时返回解析后的可调用$success,否则返回表单对象。

CSRF保护

  • FOSRESTBundle可以在特定角色上禁用CSRF保护。
  • 这不是最佳解决方案,因为同一个用户可以使用API和UI。这意味着如果他们具有ROLE_API并且登录到UI,他们不会受到CSRF保护。

APIFirstBundle提供另一种解决方案

  • 当您创建您的Form Types时,不要扩展Symfony\Component\Form\AbstractType,而是扩展BenTools\ApiFirstBundle\Form\ApiFirstAbstractType
  • 设置带有自动CSRF保护启用的表单
    /**
     * @param OptionsResolver $resolver
     */
    public function configureOptions(OptionsResolver $resolver) {
        $resolver->setDefaults([
            'data_class'      => MyResource::class,
            'csrf_protection' => $this->shouldEnableCSRFProtection(),
        ]);
    }
  • 由于其构造函数依赖于api_first.api_consumer_detector,因此将表单类型声明为服务

表单处理

当您扩展BenTools\ApiFirstBundle\Model\AbstractResourceHandler类时,您可以调用getCreationFormgetEditionFormgetDeletionForm方法。

如果您使用UI,它将创建一个命名表单。相反,如果您在API上提交数据,表单中的键将不会添加前缀。

例如,如果您使用UI创建新的联系人资源,应用程序将期望以下表单参数

[
    'contact' => [
        'firstname' => 'John',
        'lastname'  => 'Doe',
    ],
    '_token' => 'zef6rq1g6er8g1re6g81e6fertjh4yu6j4'
];

如果您使用API,应用程序将期望以下内容

[
    'firstname' => 'John',
    'lastname'  => 'Doe',
];

当然,我们也可以只使用无名称的表单。但这会导致与Symfony的_token_method隐藏字段的问题,这些字段被误解为表单的额外字段