Ruby on rails 如何在MVC下创建简洁的RESTful向导?
我试图在构建应用程序时尽可能地使用RESTful,但有一件事我永远不能确定,那就是如何创建向导类型的工作流,即RESTful和简洁 以多页注册流程为例 选项1:我可以为每个步骤创建一个控制器,并在用户进入该步骤(或返回该步骤)时调用new或edit。我以step1_控制器、step2_控制器等结束 选项2:我可以创建一个单控制器,并使用参数、会话变量、状态机等跟踪注册过程中的位置。所以我要注册控制器/步骤?id=1 第一个选项是严格的REST,但不是很简洁,最后是一些额外的控制器。第二个选项更简洁,但会打断其他选项,我愿意这样做,但我不会掉以轻心 有更好的选择吗Ruby on rails 如何在MVC下创建简洁的RESTful向导?,ruby-on-rails,asp.net-mvc,model-view-controller,rest,Ruby On Rails,Asp.net Mvc,Model View Controller,Rest,我试图在构建应用程序时尽可能地使用RESTful,但有一件事我永远不能确定,那就是如何创建向导类型的工作流,即RESTful和简洁 以多页注册流程为例 选项1:我可以为每个步骤创建一个控制器,并在用户进入该步骤(或返回该步骤)时调用new或edit。我以step1_控制器、step2_控制器等结束 选项2:我可以创建一个单控制器,并使用参数、会话变量、状态机等跟踪注册过程中的位置。所以我要注册控制器/步骤?id=1 第一个选项是严格的REST,但不是很简洁,最后是一些额外的控制器。第二个选项更简
我在RubyonRails中工作,但这个问题也适用于其他MVC实现,比如ASP.NETMVC,实际上我不太关心在一次性向导中维护REST。我认为,对于可重复的操作,REST是最重要的——您希望url基本上是可书签的,以便无论何时返回,都能获得相同的数据视图。在多步骤向导中,您的依赖关系无论如何都会破坏REST的这种透视图。我的感觉是有一个单独的控制器,具有潜在的独立操作,或者使用查询参数来指示您所处的步骤。这就是我构建激活向导(需要多个步骤)的方式。如果您在这里应用一些DDD逻辑,这是对MVC中“M”的补充,UI的状态(注册进度)属于应用层,它可以直接与域和基础结构层对话(四层:UI、应用程序、域和基础架构)。DDD的概念让您首先“思考”如何在代码中解决解决方案。让我们一步一步地完成这个 这是进度条 您希望在此处维护的状态是注册的步骤或进度。因此,我的第一步是记录进度或“步骤”。例如,步骤1:获取用户名/通行证,步骤2:获取电子邮件。在这种情况下,我将应用逻辑将模型“移动”到下一步。很可能是使用注册服务上的NextStep()方法(RegistrationService.NextStep()) 啊,但它属于应用层 我将在应用程序层创建一个名为RegistrationService的服务。我将在此处放置一个名为NextStep()的方法。但请记住,域不会在此处保留模型的状态。在这种情况下,您希望将状态集中在应用程序层。因此,在这种情况下,NextStep()将不作用于模型对象(因为它不是域责任的一部分),而是UI。因此,您需要一些东西来保持注册过程的状态 远离域模型,ViewModel怎么样? 因此,现在我们知道我们必须保留UI中某些内容的状态。MVC允许一个称为ViewModels的概念(在ASP.NET MVC中,不确定RoR如何称呼它)。ViewModel表示将由视图和/或局部视图显示的模型 ViewModel将是保存此对象状态的最佳位置当然,这意味着应用层必须保留RegistrationProgressViewModel的位置,应用层将根据NextStep操作更改其内部结构。如果它很复杂,您可能需要在应用层中创建RegistrationProgressService()并放置NextStep()在它里面把你的逻辑抽象出来 如何传递ViewModel? 最后一部分是如何跟踪该对象的状态。由于web应用程序是无状态的,因此您必须通过应用程序以外的其他方式来保持控制。在这种情况下,我将返回到以下两种方式之一:1)将ViewModel序列化到客户端,并让客户端来回传递它,或2)保留ViewModel的服务器端副本,并将某种类型的标识符来回传递给客户端 这是一个值得思考的好例子,因为我自己还没有执行过。对于#2,保存此ViewModel状态的最安全和有保障的方法是通过基础架构层将其保存到(是的,应用程序层可以直接与基础架构层对话).对我来说,这似乎是一个很大的工作,因为有些东西可能会消失,我的数据库中会有部分注册 但是,#2会将用户的私人信息(用户名、密码、电子邮件、抄送等)保存在服务器端,而不会来回传递 最后,答案! 因此,在浏览之后,我们得出了以下结论:
- 在应用程序层中创建RegistrationProgressViewModel()
- 在应用程序层中使用NextStep(ViewModel vm)方法创建RegistrationProgressService()
- 执行NextStep()时,通过基础结构层将ViewModel持久化到数据库
public class RegistrationController : Controller
{
// http://domain.com/register
public ActionResult Index()
{
return View(new RegistrationProgressViewModel);
}
// http://domain.com/register
// And this posts back to itself. Note the setting
// of "CurrentStep" property on the model below.
//
public ActionResult Index(
RegistrationProgressViewModel model)
{
// The logic in NextStep() here checks the
// business rules around the ViewModel, verifies its
// authenticity, if valid it increases the
// ViewModel's "CurrentStep", and finally persists
// the viewmodel to the DB through the Infrastructure
// layer.
//
RegistrationProgressService.NextStep(model);
switch (model.CurrentStep)
{
case 2:
// wire up the View for Step2 here.
...
return View(model);
case 3:
// wire up the View for Step3 here.
...
return View(model);
case 4:
// wire up the View for Step4 here.
...
return View(model);
default:
// return to first page
...
return View(model);
}
}
}
您会注意到,这将验证模型内部状态的“业务逻辑”抽象到RegistrationProcessService.NextStep()方法中
良好的锻炼。:)
最后,您的“RESTful”url是一个漂亮而干净的POST to:/register,它需要一个填写了特定属性的ViewModel。如果ViewModel无效,/register不会前进到