Как я могу использовать Catalyst и Uri Chain с интерфейсом REST? - PullRequest
5 голосов
/ 13 декабря 2011

Я ожидаю получить Ури как

/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
 }

Итак, проблема в том, что я установил Chained in account_GET на 'user_GET' сервер отладка показывает, что путь задан:

[debug] Loaded Chained actions:
.-----------------------------+--------------------------------------.
| Path Spec                   | Private                              |
+-----------------------------+--------------------------------------+
| /user/*/account/*           | /mcp/user_GET (1)                    |
|                             | => /mcp/account_GET                  |
'-----------------------------+--------------------------------------'

Когда я установил Chained in account_GET в значение 'user', серверная отладка показывает:

[debug] Unattached Chained actions:

[debug] Unattached Chained actions:

.-------------------------------------+--------------------------------------.
| Private                             | Missing parent                       |
+-------------------------------------+--------------------------------------+
| /mcp/account_GET                    | /mcp/user                            |
'-------------------------------------+--------------------------------------'

Проблема в том, что очевидно, что последний не устанавливается, а первый возвращаясь, что он не был найден.

Так что проблема в том, что если я звоню / user / 12345 / account / 23456, как мне получить этот путь? установлен правильно, когда то, что кажется очевидным, Chained ('user'), не является быть установленным и менее очевидный путь, Chained ('user_GET'), просто не работает?

Ответы [ 3 ]

4 голосов
/ 16 декабря 2011

Лично я бы пошел на что-то вроде следующего в пользовательском контроллере:

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 на запрос POST к действию account) кажется несколько противоречивой с точки зрения дизайна. Это может сработать, но я никогда не пробовал.

Приведенные выше примеры, конечно, упрощены. У меня обычно есть действие base в каждом контроллере, устанавливающее пространство имен и общее родительское действие, и все другие действия в контроллере будут блокировать это. Тогда у меня будет object, как указано выше для загрузки отдельных ресурсов, и root для корневого действия контроллера. Поскольку вы можете построить любую структуру дерева, она довольно гибкая. Поэтому лучшее решение часто зависит от ваших ограничений.

3 голосов
/ 13 декабря 2011

mst из # катализатора говорит:

Методы _GET / _POST не нуждаются в атрибутах отправки

1 голос
/ 14 декабря 2011

Я считаю, что выполнение чего-то подобного будет работать, однако вам придется каким-то образом передать цепочечный аргумент, либо в тайник, либо, возможно, в качестве атрибута объекта в $ 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) в конечной точке.

...