我正在开发一个使用Zend框架2实现的Web应用程序,可以通过浏览器和apis访问人类用户。
一开始,我计划为api访问编写一个额外的Rest控制器,但由于apis和人类用户在控制器中使用相同的功能,我的apis目前只是发送他们的消息(作为POST请求)非静止控制器也被人类使用。
我想知道真正的休息控制器的实现是否比我目前的方法有任何优势。谢谢。
答案 0 :(得分:3)
听起来您只是进行远程调用以形成操作,使它们同时满足提交和API调用。以下是一些注意事项:
安全性(身份验证,验证等)
如果您正确保护您的网站,那些表单操作应该在某些身份验证服务的后面,其中访问由用户登录时创建的会话/ cookie数据授予(身份验证是持久的)。因此,您还需要API调用来处理cookie。如果您只是为API调用提供单独的端点,那么维护您的应用程序会更容易。然后,您可以使用单独的身份验证服务,例如使用令牌等无状态身份验证方法,这在RESTful API中非常常见。
同样,通过API调用以及哪些操作不允许执行哪些操作更容易。最好始终确保提交针对CSRF攻击的表单提交。相反,API调用需要能够从远程源访问您的端点。因此,为API调用创建单独的接口要好得多,以避免在安全性方面做出妥协。
您的数据的表示
您提交的某些表单可能需要执行某些操作,例如重定向。在这些操作期间,您可能需要将数据写入用户会话(例如,设置将在重定向后显示的Flash消息)。通过API调用操作时,这些没有意义。
您还需要您的网站将数据表示为特定的API调用格式(XML,JSON等)。同样,当您有两个接口时,这将更容易维护,一个用于人类,并且其他用于API客户。
这就是为什么从控制器和服务中移除尽可能多的逻辑总是明智的。这样,您的所有域逻辑都集中在一个地方,您可以为您的网站生成新的接口,如RESTful控制器,而无需重复代码。
答案 1 :(得分:2)
我不会将控制器用作服务层,因为它会相互耦合到不同的接口。有两种方法可以解决这个问题。首先是使用RESTful接口创建客户端前端,另一个是将控制器逻辑卸载到可重用服务。
如果你选择第一个选项,你“只”拥有一个RESTful控制器而没有“人类”控制器。你的api使用REST接口,对于html版本你使用的是angular.js,backbone.js或ember.js。这些工具可以很好地与REST api后端一起加载页面,并且可以节省开发时间,因为您需要编写一次控制器。
第二种选择是将大部分逻辑卸载到服务层。这有助于使您的控制器变得苗条。这是我主要使用的方法。我有一个子名称空间“Api”和“Web”(如MyModule\Controller\Api\FooController
)并且完全分离。路由不同,界面不同。 RESTful控制器将REST参数应用于get(),getList()和create()等方法,Web控制器按1:1映射到页面(viewAction(),editAction()等)。
两者都使用相同的服务,因此代码重用最大化。博客文章控制器的这种服务的一个例子就是这个(使用Doctrine):
<?php
namespace Blog\Service;
use Doctrine\Common\Persistence\ObjectManager;
use Blog\Entity\Post as PostEntity;
class Post
{
protected $objectManager;
protected $objectRepository;
public function __construct(ObjectManager $objectManager)
{
$this->objectManager = $objectManager;
$this->objectRepository = $objectManager->getRepository('Blog\Entity\Post');
}
public function find($id)
{
return $this->objectRepository->find($id);
}
public function store(array $data)
{
$post = new PostEntity;
$post->fromArray($data);
$objectManager = $this->objectManager;
$objectManager->persist($post);
$objectManager->flush();
}
public function update(array $data, PostEntity $post)
{
//
}
public function delete(PostEntity $post)
{
//
}
}
这些服务既可以用于“人”控制器,也可以用于RESTful控制器。是的,您可能会有一些代码重复,但对于服务,您大多删除此重复。如果你留下了一些重复的代码,你总是要考虑: