복붙노트

[RUBY-ON-RAILS] 랙 미들웨어는 무엇입니까?

RUBY-ON-RAILS

랙 미들웨어는 무엇입니까?

루비 랙 미들웨어는 무엇입니까? 나는 그들이 "미들웨어"가 무엇을 의미하는지에 대한 좋은 설명을 찾을 수 없습니다.

해결법

  1. ==============================

    1.이 랙을 사용하여 웹 서버에 대한 파이프 라인 디자인 패턴의 구현입니다 - 미들웨어 "는 요청과 응답을 필터링 할 수있는 방법"보다 더 랙.

    이 랙을 사용하여 웹 서버에 대한 파이프 라인 디자인 패턴의 구현입니다 - 미들웨어 "는 요청과 응답을 필터링 할 수있는 방법"보다 더 랙.

    이 요청을 처리하는 여러 단계 밖으로 매우 깨끗하게 분리한다 - 잘 설계된 소프트웨어 제품의 핵심 목표 인의 분리.

    랙과 함께 예를 들어 내가하고있는 파이프 라인의 별도의 단계를 가질 수 있습니다 :

    여러 단계를 분리 할 수 ​​있다는 (선택적를 포함하는) 잘 구조화 된 응용 프로그램을 개발에 큰 도움이됩니다.

    미들웨어 랙 주변 개발 좋은 에코 시스템도있다 - 당신은 위보다 모든 단계를 수행하는 사전 제작 된 랙 구성 요소를 찾을 수 있어야합니다. 미들웨어의 목록 랙 GitHub의 위키를 참조하십시오.

    미들웨어와 지원하지만 직접 일부 작업의 실행에 포함되지 않은 소프트웨어 구성 요소 / 라이브러리를 참조 무서운 용어입니다. 매우 흔한 예는 로깅, 인증 및 기타 일반적인 수평 처리 구성 요소. 이들은 스스로를 구축 모든 사람들이 여러 응용 프로그램에서 필요하지만 너무 많은 사람들이 아닙니다 관심 (또는해야)한다는 것을 경향이있다.

  2. ==============================

    2.우선, 랙 정확히 두 가지이다 :

    우선, 랙 정확히 두 가지이다 :

    랙 - 웹 서버 인터페이스

    랙의 아주 기본적인 간단한 규칙이다. 모든 랙 준수하는 웹 서버는 항상 당신이 그를주는 객체의 호출 메서드를 호출하고 그 방법의 결과를 제공합니다. 이 호출 방법을 같이하는 방법을 정확하게 지정 랙, 그리고 무엇을 반환해야한다. 그의 랙.

    의 그것에게 간단한 시도해 보자. 나는 랙 준수하는 웹 서버로에 WEBrick을 사용 하겠지만, 그 중 하나는 할 것입니다. 하자가 반환하는 간단한 웹 응용 프로그램 JSON 문자열을 만들 수 있습니다. 이를 위해 우리는 config.ru라는 파일을 만듭니다. config.ru는 자동으로 단순히 랙 호환 웹 서버에있는 config.ru의 내용을 실행 랙 보석의 명령 rackup에 의해 호출됩니다. 그럼이 (가) config.ru 파일에 다음을 추가 할 수 있습니다 :

    class JSONServer
      def call(env)
        [200, {"Content-Type" => "application/json"}, ['{ "message" : "Hello!" }']]
      end
    end
    
    map '/hello.json' do
      run JSONServer.new
    end
    

    협약 지정로서의 서버 환경 해시를 받아 웹 서버를 제공하기위한 형태 [상태, 헤더, 바디] 배열을 리턴하는 메소드 호출 통화를 갖는다. 의는 단순히 rackup를 호출하여 사용해보십시오. 기본 어쩌면에 WEBrick 또는 잡종 시작하고 즉시 봉사 요청을 기다립니다, 호환 서버 랙.

    $ rackup
    [2012-02-19 22:39:26] INFO  WEBrick 1.3.1
    [2012-02-19 22:39:26] INFO  ruby 1.9.3 (2012-01-17) [x86_64-darwin11.2.0]
    [2012-02-19 22:39:26] INFO  WEBrick::HTTPServer#start: pid=16121 port=9292
    

    하자 검사 중 컬링 또는 방문하여 우리의 새로운 JSON 서버의 URL에 http : // localhost를 : 9292 / hello.json 봐라 :

    $ curl http://localhost:9292/hello.json
    { message: "Hello!" }
    

    효과가있다. 큰! 모든 웹 프레임 워크의 기초이다 그, 그것은 레일 또는시나합니다. 어떤 시점에서 그들은 프레임 워크 코드 모두를 통해 호출 방법, 작업을 구현하고, 마지막으로 [헤더, 신체 상태] 형태로 전형적인에서 응답을 반환합니다.

    예를 들어, 루비 온 레일즈에서 랙 요청은 ActionDispatch :: 같은 외모 Routing.Mapper 클래스 안타 :

    module ActionDispatch
      module Routing
        class Mapper
          ...
          def initialize(app, constraints, request)
            @app, @constraints, @request = app, constraints, request
          end
    
          def matches?(env)
            req = @request.new(env)
            ...
            return true
          end
    
          def call(env)
            matches?(env) ? @app.call(env) : [ 404, {'X-Cascade' => 'pass'}, [] ]
          end
          ...
      end
    end
    

    그러니까 기본적으로 수표, 어떤 경로가 일치하는 경우 ENV 해시에 따라 레일. 이 응답을 계산하는 응용 프로그램에 ENV 해시를 통과 할 수 있도록 어떤 웹 서버가 랙 인터페이스 규칙을 준수 그래서 그렇지 않으면 즉시 404로 응답하는 경우, 완전히 날려 Rails 애플리케이션을 제공 할 수 있습니다.

    미들웨어

    또한 미들웨어 층의 생성을 지원 랙. 그들은 기본적으로 요청 절편 그것으로 뭔가를하고 그것을 전달합니다. 이 다양한 작업에 매우 유용합니다.

    하자 우리는 조치 요청이 걸리는 것을 우리 JSON 서버에 로깅을 추가하고 싶은 말은. 우리는 단순히 정확히이 일을 미들웨어 로거를 만들 수 있습니다 :

    class RackLogger
      def initialize(app)
        @app = app
      end
    
      def call(env)
        @start = Time.now
        @status, @headers, @body = @app.call(env)
        @duration = ((Time.now - @start).to_f * 1000).round(2)
    
        puts "#{env['REQUEST_METHOD']} #{env['REQUEST_PATH']} - Took: #{@duration} ms"
        [@status, @headers, @body]
      end
    end
    

    이 작성되는 경우, 그 자체를 실제 랙 응용 프로그램의 복사본을 저장합니다. 우리의 경우 우리 JSONServer의 인스턴스이다 그. 자동 랙 미들웨어에 호출 메서드를 호출하고이 기대는 우리의 JSONServer 반환처럼 [상태, 헤더, 신체] 배열을 백업 할 수 있습니다.

    그래서 미들웨어, 시작점은 다음 JSONServer에 실제 호가 @ app.call (ENV)으로 구성되어, 촬영 후, 기록 장치는, 로그 엔트리를 출력하고, 마지막으로 [@status, @headers로서 응답을 리턴 @ 몸].

    우리의 작은 rackup.ru는이 미들웨어를 사용하여 이런 식으로 사용 RackLogger를 추가로 만들려면 :

    class JSONServer
      def call(env)
        [200, {"Content-Type" => "application/json"}, ['{ "message" : "Hello!" }']]
      end
    end
    
    class RackLogger
      def initialize(app)
        @app = app
      end
    
      def call(env)
        @start = Time.now
        @status, @headers, @body = @app.call(env)
        @duration = ((Time.now - @start).to_f * 1000).round(2)
    
        puts "#{env['REQUEST_METHOD']} #{env['REQUEST_PATH']} - Took: #{@duration} ms"
        [@status, @headers, @body]
      end
    end
    
    use RackLogger
    
    map '/hello.json' do
      run JSONServer.new
    end   
    

    서버를 재시동 늘리면, 그것은 모든 요청에 ​​로그를 출력한다. 랙은 추가되는 순서대로 호출되는 여러 미들웨어를 추가 할 수 있습니다. 그냥 랙 응용 프로그램의 핵심을 변경하지 않고 기능을 추가 할 수있는 좋은 방법입니다.

    랙 - 젬을

    랙 있지만 - 무엇보다도 - 컨벤션이 또한 훌륭한 기능을 제공하는 보석이다. 그 중 하나는 우리는 이미 우리의 JSON 서버의 rackup 명령에 사용. 하지만 더있다! 랙 보석은 정적 파일 또는 전체 디렉토리를 제공하는 것처럼, 사용 사례에 대한 많은 작은 응용 프로그램을 제공합니다. 이제 우리는 아주 기본적인 HTML 파일이 htmls / index.html을에있는 예를 들어, 간단한 파일을 제공하는 방법을 보자 :

    <!DOCTYPE HTML>
      <html>
      <head>
        <title>The Index</title>
      </head>
    
      <body>
        <p>Index Page</p>
      </body>
    </html>
    

    우리는 어쩌면 그래서 우리 config.ru에 다음을 추가 할 수 있도록, 웹 사이트의 루트에서이 파일을 제공 할 :

    map '/' do
      run Rack::File.new "htmls/index.html"
    end
    

    우리가 방문하는 경우에 http : // localhost를 : 9292 우리가 완벽하게 렌더링 된 우리의 html 파일을 참조하십시오. 그의는 쉽게 옳았다?

    의는 / 자바 스크립트에서 일부 자바 스크립트 파일을 작성하고하여 config.ru에 다음을 추가하여 자바 스크립트 파일의 전체 디렉토리를 추가하자 :

    map '/javascripts' do
      run Rack::Directory.new "javascripts"
    end
    

    서버를 다시 시작하고 HTTP를 방문 : // localhost를 : 9292 / 자바 스크립트 당신은 당신이 바로 어디에서 지금 포함 할 수있는 모든 자바 스크립트 파일의 목록이 표시됩니다.

  3. ==============================

    3.나는 시간의 좋은 금액에 대한 자신 랙 이해하는 문제가 있었다. 난 단지 완전히이 소형 루비 웹 서버 나 자신을 만드는 작업 후를 이해했다. 여기 내 블로그에 (이야기의 형태로) 랙에 대한 나의 교훈을 공유했습니다 http://gauravchande.com/what-is-rack-in-ruby-rails

    나는 시간의 좋은 금액에 대한 자신 랙 이해하는 문제가 있었다. 난 단지 완전히이 소형 루비 웹 서버 나 자신을 만드는 작업 후를 이해했다. 여기 내 블로그에 (이야기의 형태로) 랙에 대한 나의 교훈을 공유했습니다 http://gauravchande.com/what-is-rack-in-ruby-rails

    피드백은 환영 이상입니다.

  4. ==============================

    4.config.ru 최소 실행 가능한 예

    config.ru 최소 실행 가능한 예

    app = Proc.new do |env|
      [
        200,
        {
          'Content-Type' => 'text/plain'
        },
        ["main\n"]
      ]
    end
    
    class Middleware
      def initialize(app)
        @app = app
      end
    
      def call(env)
        @status, @headers, @body = @app.call(env)
        [@status, @headers, @body << "Middleware\n"]
      end
    end
    
    use(Middleware)
    
    run(app)
    

    실행 rackup 및 방문 로컬 호스트 : 9292. 출력은 다음과 같습니다

    main
    Middleware
    

    그래서 미들웨어는 랩과 주요 응용 프로그램을 호출하는 것이 분명하다. 그러므로 사전 처리 요청 및 후 공정 어떤 방법으로 응답 할 수 있습니다.

    에서 설명했듯이 : http://guides.rubyonrails.org/rails_on_rack.html#action-dispatcher-middleware-stack, 용도는 그것의 많은 기능을위한 미들웨어 랙 레일, 당신은 당신이 config.middleware.use에 너무 자신의 추가 할 수 있습니다 가족 방법.

    미들웨어의 기능을 구현의 장점은 그냥 레일, 어떤 랙 프레임 워크에 따라서 모든 주요 루비 사람을 재사용하고, 수 없다는 것입니다.

  5. ==============================

    5.미들웨어 응용 프로그램에 들어오는 요청과 응답을 필터링하는 방법입니다 랙. 미들웨어 구성 요소는 인바운드 요청 및 아웃 바운드 응답을 처리, 클라이언트와 서버 사이에 위치하지만, 더 많은 웹 서버와 통신하는 데 사용할 수있는 인터페이스보다입니다. 보통 루비 클래스입니다 그룹 및 주문 모듈로 사용하고, 그들 사이의 의존성을 지정합니다. 미들웨어 모듈은 반드시 랙 - 응답을 매개 변수로 환경 해시를한다 "호출"방법에 - 매개 변수로 스택에 다음 응용 프로그램을 소요 생성자가 있습니다. 상태 코드 환경 해시 응답 본문이 호출의 값을 반환하는 배열이다.

    미들웨어 응용 프로그램에 들어오는 요청과 응답을 필터링하는 방법입니다 랙. 미들웨어 구성 요소는 인바운드 요청 및 아웃 바운드 응답을 처리, 클라이언트와 서버 사이에 위치하지만, 더 많은 웹 서버와 통신하는 데 사용할 수있는 인터페이스보다입니다. 보통 루비 클래스입니다 그룹 및 주문 모듈로 사용하고, 그들 사이의 의존성을 지정합니다. 미들웨어 모듈은 반드시 랙 - 응답을 매개 변수로 환경 해시를한다 "호출"방법에 - 매개 변수로 스택에 다음 응용 프로그램을 소요 생성자가 있습니다. 상태 코드 환경 해시 응답 본문이 호출의 값을 반환하는 배열이다.

  6. ==============================

    6.나는 몇 가지 문제를 해결하기 위해 랙 미들웨어를 사용했습니다 :

    나는 몇 가지 문제를 해결하기 위해 랙 미들웨어를 사용했습니다 :

    이 두 경우 모두에서 꽤 우아한 수정 여유.

  7. ==============================

    7.랙 루비 루비 워크지지 웹 서버 간의 최소한의 인터페이스를 제공한다.

    랙 루비 루비 워크지지 웹 서버 간의 최소한의 인터페이스를 제공한다.

    당신이 랙 응용 프로그램을 작성할 수 있습니다 랙 사용.

    랙은 원하는 무엇이든이 해시에 포함 된 것을 사용하여 랙 응용 프로그램 (CGI와 같은 헤더로 구성, 클라이언트로부터 HTTP 요청 안에 포함 된 해시) 환경 해시를 전달합니다.

    매개 변수로 환경 해시와 #call 방법에 대한 응답 (일반적으로 ENV로 정의) 것을 객체 - 랙을 사용하려면, 당신은 '응용 프로그램'을 제공해야합니다. #call 정확히 세 값의 배열을 반환해야합니다 :

    당신은 반환과 같은 배열하는 랙 응용 프로그램 쓸 수 있습니다 -이 응답 내부 랙에 의해, 클라이언트로 다시 전송됩니다 (이 실제로 클래스 랙 :: 응답의 인스턴스가 될 것입니다 [문서로 이동 클릭).

    우리는 응답 본문의 반환 응답 (랙 :: 응답의 인스턴스) 문자열이 포함 된 배열하는 작은 랙 응용 프로그램을 만들 것입니다 : "안녕하세요, 세계를".

    우리는 명령 rackup을 사용하여 로컬 서버를 발사합니다.

    우리의 브라우저에서 해당 포트를 방문 할 때 우리는 "안녕하세요, 세계!"볼 뷰포트에서 렌더링.

    #./message_app.rb
    class MessageApp
      def call(env)
        [200, {}, ['Hello, World!']]
      end
    end
    
    #./config.ru
    require_relative './message_app'
    
    run MessageApp.new
    

    9292 그리고 당신은 볼 수 : rackup 및 방문 로컬 호스트와 로컬 서버를 화재 '안녕하세요, 세계!' 렌더링.

    이 포괄적 인 설명이 아니라 본질적으로 무슨 일이 일어나는 클라이언트 (브라우저) 로컬 서버를 통해, 랙하는 HTTP 요청을 보내는, 그리고 랙 MessageApp 및 실행이에 매개 변수로 환경 해시를 전달 호출 인스턴스 방법합니다 (ENV 인수).

    랙은 랙 :: 응답의 인스턴스를 생성하는 리턴 값 (어레이) 및 용법을 취하고 클라이언트에게 그 위로 보낸다. 브라우저 인쇄 할 마법 사용 '안녕하세요, 세상을!' 화면에.

    덧붙여, 당신은 환경 해시 외모 그냥 넣어 둔다는 아래 데프 (ENV)를 호출 봉투, 좋아하는 것을보고 싶어합니다.

    그대로 최소, 당신이 여기에 쓴 것은 랙 응용 프로그램입니다!

    우리의 작은 랙 응용 프로그램에서, 우리는 (환경 해시에 대한 자세한 여기를 참조) ENV 해시와 상호 작용할 수 있습니다.

    우리는 환경 해시의 키 / 값 쌍 중 하나의 값으로 캡슐화 된 URL에 자신의 쿼리 문자열은, 따라서, 해당 문자열은 HTTP 요청에 존재합니다 입력 사용자의 능력을 구현합니다.

    우리의 랙 응용 프로그램은 환경 해시에서 해당 쿼리 문자열에 액세스하고 응답의 몸을 통해 (이 경우 우리의 브라우저) 클라이언트가 다시 보내드립니다.

    환경 해시에 랙 문서에서 : "QUERY_STRING :.? 비어있을 수 있지만, 어떤 경우에는, 항상 필요한 다음과 요청 URL의 일부!"

    #./message_app.rb
    class MessageApp
      def call(env)
        message = env['QUERY_STRING']
        [200, {}, [message]]
      end
    end
    

    이제 rackup 및 방문 로컬 호스트 : (? 안녕하세요 쿼리 문자열 인) 9292 안녕하세요 당신이 볼 수 '안녕하세요'뷰포트에서 렌더링.

    우리는 것입니다 :

    첫째, '긴 손'버전 :

    #./middleware/message_setter.rb
    class MessageSetter
      def initialize(app)
        @app = app
      end
    
      def call(env)
        if env['QUERY_STRING'].empty?
          env['MESSAGE'] = 'Hello, World!'
        else
          env['MESSAGE'] = env['QUERY_STRING']
        end
        @app.call(env)
      end
    end
    
    #./message_app.rb (same as before)
    class MessageApp
      def call(env)
        message = env['QUERY_STRING']
        [200, {}, [message]]
      end
    end
    
    #config.ru
    require_relative './message_app'
    require_relative './middleware/message_setter'
    
    app = Rack::Builder.new do
      use MessageSetter
      run MessageApp.new
    end
    
    run app
    

    랙 :: 빌더 문서에서 우리는 랙을 볼 :: Builder는 반복적으로 구조 랙 애플리케이션에 작은 DSL을 구현합니다. 하나 이상의 미들웨어 및 파견에 '바닥 수준'응용 프로그램으로 구성된 '스택'을 구축 할 수 있음이 기본적으로 의미합니다. 수익 수준의 응용 프로그램을 통해가는 모든 요청은 먼저 미들웨어 (들)에 의해 처리됩니다.

    #use 지정하는 스택으로 사용 미들웨어. 이 인수로 미들웨어를합니다.

    미들웨어해야 랙 :

    우리의 경우, '미들웨어'MessageSetter의 '생성자'는 것은 MessageSetter의 초기화 방법, 스택의 '다음 응용 프로그램은'MessageApp이다.

    그래서 여기, 때문에 어떤 랙 :: Builder는 후드 아래에 수행, MessageSetter의 초기화 방법의 응용 프로그램 인수 MessageApp이다.

    (이동하기 전에 위의 주위에 당신의 머리를 얻을)

    따라서, 기본적으로 미들웨어의 각 부분은 체인의 다음 응용 프로그램에 대한 기존의 환경 해시를 '아래로 통과'- 당신이 스택의 다음 응용 프로그램에 전달하기 전에 미들웨어 내에서 해당 환경 해시를 돌연변이 수있는 기회를 가질 수 있도록.

    #run는 응답이 #call하는 것이 목적이며, 랙 응답 (랙 :: 응답의 인스턴스)를 반환하는 인수를 사용합니다.

    랙을 사용하여 :: 빌더는 미들웨어의 체인 및 응용 프로그램에 대한 요청을 만들 수 있습니다 것은 결국 (우리의 경우, MessageApp에서) 스택의 마지막 조각에 의해 처리되기 전에 차례로 각 미들웨어에 의해 처리됩니다. 이 분리 아웃 때문에 처리 요청의 다른 단계를이 매우 유용합니다. '의 분리'의 ​​측면에서 훨씬 청소기 수 없습니다!

    당신은 여러 미들웨어로 구성된 '요청 파이프 라인'을 구축 할 수와 같은 것들로 거래 :

    (이 스레드에서 다른 답변에서 총알 점 이상)

    당신은 종종 전문시나 응용 프로그램이 표시됩니다. 시나 사용하는 랙! 시나가 무엇인지에 대한 정의 여기를 참조하십시오!

    마지막 참고로, 우리의 config.ru는 동일한 기능을 생산, 짧은 손 스타일로 작성할 수 있습니다 (이것은 당신이 일반적으로 볼 것입니다) :

    require_relative './message_app'
    require_relative './middleware/message_setter'
    
    use MessageSetter
    run MessageApp.new
    

    그리고 여기에 세 가지 인수를 필요로 명시 적으로 보여줍니다 #call는 랙 :: 응답의 새로운 인스턴스를 생성하는 것을 그 '긴 손'버전입니다, 더 명시 적으로 MessageApp가 무엇을하고 있는지 표시합니다.

    class MessageApp
      def call(env)
        Rack::Response.new([env['MESSAGE']], 200, {})
      end
    end
    
  8. ==============================

    8.랙 - 웹 및 응용 프로그램 서버 w 인터페이스 B /

    랙 - 웹 및 응용 프로그램 서버 w 인터페이스 B /

    랙은 웹 서버가 응용 프로그램과 통신하기위한 인터페이스를 제공하는 루비 패키지입니다. 웹 서버와 방법 귀하의 요청 / 응답 동작합니다을 수정하는 응용 프로그램 사이에 미들웨어 구성 요소를 쉽게 추가 할 수 있습니다. 미들웨어 구성 요소는 인바운드 요청 및 아웃 바운드 응답을 처리, 클라이언트와 서버 사이에 앉아있다.

    평신도 즉, 서버와 레일 응용 프로그램 (또는 다른 루비 웹 응용 프로그램)이 서로 대화하는 방법에 대한 지침 단지 설정 기본적으로.

    통화 방법에 대한 응답은, 매개 변수로 환경 해시를 복용하고, 세 가지 요소를 가진 Array을 반환하는 것을 목적 : 랙을 사용하기 위해, "응용 프로그램"을 제공 :

    더 설명은, 당신은 아래 링크를 따를 수 있습니다.

    1. https://rack.github.io/
    2. https://redpanthers.co/rack-middleware/
    3. https://blog.engineyard.com/2015/understanding-rack-apps-and-middleware
    4. https://guides.rubyonrails.org/rails_on_rack.html#resources
    

    레일, 우리는 랙 파일로 config.ru을 가지고, 당신은 rackup 명령을 사용하여 모든 랙 파일을 실행할 수 있습니다. 그리고 이것에 대한 기본 포트는이를 테스트하기 위해 9292., 당신은 단순히 당신의 레일 디렉토리에 rackup 실행하고 결과를 볼 수 있습니다. 당신은 또한 당신이 그것을 실행하려는 포트를 할당 할 수 있습니다. 특정 포트가에 명령 랙 파일을 실행합니다

    rackup -p PORT_NUMBER
    
  9. from https://stackoverflow.com/questions/2256569/what-is-rack-middleware by cc-by-sa and MIT license