2009-12-21 4 views
2

오랫동안 Ruby and Rails 사용자로서, Rails에서 get-and-redirect 패턴에 대해 실제로 생각해 본 적이 없었습니다. 이것의 전형적인 예는 생성() 액션을 호출 한 다음 새로 만든 항목을 표시하는 표시() 액션에 사용자를 리디렉션 될 것이다 : 그러나redirect_to가 RESTful 앱에서 제대로 작동하지 않습니까?

 
class JournalEntries 

    def index 
    @entries = JournalEntry.all 
    end 

    def create 
    @entry = JournalEntry.new(:name => "to-do list") 
    @entry.save 
    redirect_to :action => "index" 
    end 
end 

을, 이것은 당신이 고유의 단점이있다 네트워크 트래픽이 두 배로 증가합니다. 이렇게하면 대역폭 비용이 증가 할뿐만 아니라 사용자의 사이트 경험이 느려집니다.

은 왜 그냥 대신이 작업을 수행 할 :

 
    def create 
    @entry = JournalEntry.new(:name => "to-do list") 
    @entry.save 
    index 

동일한 출력 및 불필요한 오버 헤드가 필요하지 않습니다. 그러나이 외에도 훨씬 더 심각한 문제가 있습니다. redirect_to는 GET을 사용하여 리디렉션 만 할 수 있습니다. 이로 인해 네 가지 HTTP 메소드를 사용하는 RESTful 앱에 큰 문제가 발생합니다.

제 경우에는 사용자가/journal/8을 호출하고 해당 ID로 저널을 검색 할 수 있기를 바랍니다. 발견되지 않으면, 나는 비어있는 새 저널 객체를 만들고 싶었습니다. 두 경우 모두 Journal 개체가 호출자에게 전송됩니다.

RESTful 레일스의 create() 메소드는 "POST/players"에서 라우팅된다는 점에 유의하십시오. 그러나 redirect_to (및 기본 HTTP 리디렉션)는 GET 요청 만 보낼 수 있기 때문에 실제로 index /() 메서드 인 "GET/players"로 리디렉션됩니다. 이 동작은 분명히 잘못되었습니다.

내가 생각할 수있는 유일한 해결책은 단순히 위의 예제에서와 같이 redirect_to() 대신 create()를 호출하는 것입니다. 잘 작동하는 것 같습니다.

redirect_to가 동작을 직접 호출하는 것보다 선호되는 이유에 대한 의견이 있으십니까?

답변

0

나는 파이썬/장고 사람이야,하지만 리디렉션에 대한 이유는 불가지론 언어 : "데이터를 다시 보내기"

  1. 가 페이지 새로 고침을 할 경우 그들은 그 짜증나는하지 않습니다 팝업.
  2. 사용자가보고있는 페이지에 대해 완전히 깨끗한 RESTful URL을 제공합니다. POST를 사용하면 그다지 중요하지 않을 수 있습니다. 그러나 GET이 업데이트에 사용 된 경우 매달려있는 매개 변수를 확실히 제거하려고합니다.
+0

두 번째 지점에 대한 주석. 내가 이해 한대로, REST의 한 가지 점은 결코 GET으로 업데이트를하지 않는 것이므로 결코 문제가 될 수 없다. –

+0

@ 지미 : 적절한 REST에서는 동의하지 않을 것입니다. –

+0

그래서 둘 다 말하는 것을 기반으로하면, 문제는 내가하려는 것은 본질적으로 비 안정적이라는 것입니다. 만약 존재한다면 객체를 반환하고 그렇지 않으면 객체를 생성하기를 원한다면 GET/journal/1 (레코드가 반환되지 않으면 클라이언트가 호출 함) POST/journals/[POST 데이터 : journal.id = 5] 맞습니까? 즉, 단일 작업으로 둘 다 수행하는 REST에는 원 샷 호출이 없습니다. – mrjake2

2

페이지를 새로 고침하면 '데이터 재전송'이라고 표시되지 않습니다. 팝업

팝업이 성가신 일이 아닙니다. 대부분의 사용자에게는 의미가 없습니다. 사용자가 "예, POST를 다시 수행"을 클릭하면 다른 필기장 항목이 생성됩니다. 또는 무엇이든).

또한 URL이 /posts이 아닌 /posts/create 대신에 사용자가 복사/재사용 할 수 없으므로 귀찮습니다.

+0

필자의 경우 사실이 아니기 때문에 사용자는 원래의 요청에서 생성하고자하는 객체의 ID를 다른 응용 프로그램에서 전달하고있다. 따라서 POST를 다시 시도하면 ID가있는 객체의 사본 만 반환됩니다. – mrjake2

2

당신이 지적한대로 그 이유가 있습니다. GET 요청으로 리다이렉트한다. 이것은 POST (POST/PUT으로 업데이트 만하고 GET으로 데이터 만 받는다.

리다이렉션은 리디렉션에 약간의 오버 헤드를 제공하지만 POST 데이터 및 리디렉션 (브라우저에 새 URL 만 전송 함)을 제외하고 브라우저와 서버간에 실제로 데이터가 전송되지 않으므로 bandwith의 문제가 우려라고 생각하지 마십시오.

그러나 다른 점에, 당신은 ( redirect_to :index를 호출하여)/저널로 리디렉션 안, 당신은 당신이 제대로 경로를 설정 한 경우에 대해 작동하는 ( redirect_to @entry를 호출하여) 새로 만든 저널 항목에 리디렉션해야 예를 map.resources :journals

업데이트 : 존재하지 않는 경우 전표를 작성하기위한, 더 많은 유저에게 입력을 요청해야

나는 생각한다. 항목을 만드는 이유는 무엇입니까? 항목에는 사용자가 입력 한 텍스트 나 다른 입력이 있어야하므로 REST (레일) 관점에서 실제로 사용자가 추가 정보를 입력 할 수있는 new() 메서드 (GET 요청 포함)로 리디렉션해야한다고 생각합니다. 그러면 입력을 POST하고 항목을 작성한 후 새로 작성된 항목으로 재 지정합니다.

추가 정보가 필요하지 않은 경우 RESTful 방식으로 수행하는 방법을 잘 모르겠지만 생성 논리를 별도의 방법으로 입력하면됩니다. create()show() 메서드에서 호출 한 다음 show()을 계속 사용하여 리디렉션하지 않고 리소스 메서드를 호출하지 않을 것입니다.

+0

먼저 내 게시물의 두 번째 절반부터 시작해야한다고 가정합니다. 내 기본 문제는 네트워크 오버 헤드가 아니라 실제 메소드가 호출되는 것입니다. 내 컨트롤러의 관점에서 (메서드를 호출하는 방법에 대해 전혀 생각하지), Journal.show()에 대한 호출을 호출하여 Journal.create()를 호출하여 해당 저널을 찾지 못하면 반환하려고합니다. 생성 된 객체 내가 알 수있는 한, 원래 게시물에 명시된 이유로 REST 애플리케이션에서 redirect_to를 사용하여이 작업을 수행 할 수있는 방법이 전혀 없습니다. 내가 놓친 게 있니? – mrjake2

+0

지미 : 필자의 경우 실제로는 별도의 응용 프로그램에서 가져온 개체 ID 이외의 사용자 제공 데이터가 없습니다. create 메소드는 객체에 일반적인 데이터를 채우고 반환합니다. 호출자는 클라이언트 응용 프로그램에서 객체를 조작합니다.궁극적으로 나는 마지막 단락에서 정확히 맞았다 고 생각한다 - show()와 create()를 호출하는 컨트롤러에서 protected initialize_with_defaults() 메소드가 필요하다. – mrjake2

관련 문제