我期待收到像uri一样的
/user/*/account/*
我有一个定义为
的用户功能sub user :Path('/user') :PathPart('') :ActionClass('REST' ) {}
然后
sub user_GET :PathPart('user') Chained('/') CaptureArgs(1) {
#do stuff
}
对于我同样定义它们的帐户。
sub account :Path('/account') :PathPart('') :ActionClass('REST') {}
sub account_GET :PathPart('account') Chained('user_GET') Args(1) {
#do stuff
}
所以,问题是当我将account_GET中的Chained设置为服务器的'user_GET'时 debug显示路径已设置:
[debug] Loaded Chained actions:
.-----------------------------+--------------------------------------.
| Path Spec | Private |
+-----------------------------+--------------------------------------+
| /user/*/account/* | /mcp/user_GET (1) |
| | => /mcp/account_GET |
'-----------------------------+--------------------------------------'
当我将account_GET中的Chained设置为'user'时,服务器调试显示:
[debug] Unattached Chained actions:
[debug] Unattached Chained actions:
.-------------------------------------+--------------------------------------.
| Private | Missing parent |
+-------------------------------------+--------------------------------------+
| /mcp/account_GET | /mcp/user |
'-------------------------------------+--------------------------------------'
问题是,显然后者没有建立而前者是 回来说没找到。
所以问题是如果我正在调用/ user / 12345 / account / 23456我该如何获得该路径 当看起来很明显的路径时,链接('用户')没有正确设置 被设置和不太明显的路径,Chained('user_GET'),根本就没有用?
答案 0 :(得分:4)
就个人而言,我会在用户控制器中使用以下内容:
package MyApp::Controller::User;
...
# root of the chain
sub object: Chained PathPart('user') CaptureArgs(1) { ... }
上面的object
操作会将用户对象加载到存储中。现在我将用户控制器链接到上面,如下所示:
package MyApp::Controller::User::Account;
...
# chains to the action loading the user object and dispatches RESTy
sub account: Chained('/user/object') ActionClass('REST') Args(1) { ... }
# handle individual request methods
sub account_GET { ... }
sub account_POST { ... }
此处account
操作为执行实际操作的account_*
方法提供了公共数据。
将特定于方法的操作作为链的一部分(比如让user
对account
操作的POST请求作出反应)从设计的角度看似乎有点违反直觉。这可能有用,但我从未尝试过。
以上示例当然是简化的。我通常在每个控制器中设置base
动作,设置命名空间和公共父动作,控制器中的所有其他动作将链接该动作。然后我会在上面加object
来加载单个资源,并为控制器的根操作设置root
。由于您可以构建任何类型的树结构,因此它非常灵活。因此,最佳解决方案通常取决于您的约束条件。
答案 1 :(得分:3)
答案 2 :(得分:1)
我相信做类似下面的事情会有效,但你必须以某种方式传递链式参数,无论是在存储中,还是作为$ self中的对象属性。
sub base
:Chained('/')
:PathPart('')
:CaptureArgs(0)
{
my ( $self, $c ) = @_;
}
sub user_account
:Chained('/')
:PathPart('user')
:CaptureArgs(1)
:ActionClass('REST')
{
my ( $self, $c, $user_id ) = @_;
}
sub user_account_GET
:Chained('user')
:PathPart('account')
:Args(1)
{
my ( $self, $c ) = @_;
}
这是它创建的路径规范
[debug] Loaded Chained actions:
.-------------------------------------+--------------------------------------.
| Path Spec | Private |
+-------------------------------------+--------------------------------------+
| /user/*/account/* | /user/base (0) |
| | -> /user/user_account (1) |
| | => /user/user_account_GET |
:Chained('/')
当然意味着链条的开始。 :Chained('user_account')
基本上意味着在此控制器中查找一个名为user_account
的子程序,如果你放:Chained('/user_account')
它将开始在根控制器中查找(这有点复杂因为你可以在根控制器之外建立全局链接。 :PathPart('foo')
确定实际URI的组件。显然,您需要在中点使用:CaptureArgs(1)
,在结束点使用:Args(1)
。