Rack相关知识梳理(三)

简介: Rack为编写Web应用以及Web框架提供了很多便利的工具,那么这一节,我们实现一个最简单的Web框架。 一、Web框架应该具备什么功能 对request和response的存取 路由:根据不同URL执行不同程序 能够处理cookies 能够存取session 能够生成日志 ...... 看上去挺麻

Rack为编写Web应用以及Web框架提供了很多便利的工具,那么这一节,我们实现一个最简单的Web框架。

 

一、Web框架应该具备什么功能


  • 对request和response的存取


  • 路由:根据不同URL执行不同程序


  • 能够处理cookies


  • 能够存取session


  • 能够生成日志


  • ......

 

看上去挺麻烦的,是吧?其实,则不然


前面我们已经知道Rack::Request和Rack::Response这两个类可以用来处理request和 response,那么我们该如何实现路由呢?Rack提供Rack::URLMap类来处理路由,我们这里可以不直接使用这个类,如果大家仔细看Rack::Builder的实现,大家会发现这个类提供了一个map方法以及generate_map方法:


map

def map(path, &block) 
  @map ||= {} 
  @map[path] = block
end


generate_map


def generate_map(default_app, mapping)
  mapped = default_app ? {'/' => default_app} : {}
  mapping.each { |r,b| 
    mapped[r] = self.class.new(default_app, &b).to_app 
  } 
  URLMap.new(mapped)
end


路由的作用其实就是根据URL请求的路径去调用对应的程序,因此map方法它接受路径path和 对应的程序&block,然后用hash保存其对应关系generate_map这个方法是在to_app中调用的,它主要通过URLMap建立起路由和所执行应用程序的关系。


def to_app
  app = @map ? generate_map(@run, @map) : @run 
  fail "missing run or map statement" unless app
  app = @use.reverse.inject(app) { |a,e| e[a] } 
  @warmup.call(app) if @warmup
  app
end


前面我们知道to_app方法是为了组合中间件以及应用程序的,通过这段代码我们可以看出来, 在组合中间件之前需要先根据路由找到真正的run,然后再组装对应的中间件。

 

二、一个简单的Web框架


下面是一个简单的web框架,具备对request、response的处理并且具有路由、日志功能。


require 'rack'
app = Rack::Builder.new { 
  use Rack::ContentLength 
  map '/hello' do
    use Rack::CommonLogger 
    map '/user1' do
      run lambda {|env| 
        [200, {"Content-type" => "text/html"}, ["from user1", "SCRIPT_NAME=#{env["SCRIPT_NAME"]}", "PATH_INFO=#{env["PATH_INFO"]}"]]
      }
    end
    map '/everyone' do
      run lambda {|env| [200, {"Content-type" => "text/html"},
["from everyone", "SCRIPT_NAME=#{env["SCRIPT_NAME"]}", "PATH_INFO=#{env["PATH_INFO"]}"]]
      }
    end
    map '/' do
      run lambda {|env| [200, {"Content-type" => "text/html"},
["from hello catch all", "SCRIPT_NAME=#{env["SCRIPT_NAME"]}", "PATH_INFO=#{env["PATH_INFO"]}"]]
      }
    end 
  end
  map '/' do
    run lambda {|env| [200, {"Content-type" => "text/html"}, ["root"]]
    }
  end
}.to_app
Rack::Handler::WEBrick.run app, :Port => 3000


通过上面代码可以看出来:


  • map是可以嵌套的


  • 可以对不同的路由使用不同的中间件组合

 

三、rackup


前面我们的代码中最后一行总是这样写的:


Rack::Handler::WEBrick.run xxx, :Port => 3000


这样做写死了所要用的服务器,不灵活。


Rack提供了rackup命令,允许我们用一个配置文件去执行我们的应用程序,rackup使用很简单,我们只需要提供一个后缀为.ru的配置文件即可,然后运行 rackup xxx.ru就ok了,我们把 前面代码改为:


map '/hello' do 
  map '/user1' do
    run lambda {|env| [200, {"Content-type" => "text/html"}, ["from user1",
"SCRIPT_NAME=#{env["SCRIPT_NAME"]}", "PATH_INFO=#{env["PATH_INFO"]}"]]
    }
  end
  map '/everyone' do
    run lambda {|env| [200, {"Content-type" => "text/html"},
["from everyone", "SCRIPT_NAME=#{env["SCRIPT_NAME"]}", "PATH_INFO=#{env["PATH_INFO"]}"]]
    }
  end
  map '/' do
    run lambda {|env| [200, {"Content-type" => "text/html"},
["from hello catch all", "SCRIPT_NAME=#{env["SCRIPT_NAME"]}", "PATH_INFO=#{env["PATH_INFO"]}"]]
    }
  end 
end
map '/' do
  run lambda {|env| [200, {"Content-type" => "text/html"}, ["root"]]
  }
end


保存上述代码到config.ru文件然后运行 rackup config.ru即可。

相关文章
|
3月前
|
Kubernetes Docker Python
dockercompose与k8s的pod文件的爱恨情仇
dockercompose与k8s的pod文件的爱恨情仇
|
4月前
|
Kubernetes Linux 网络虚拟化
15张图超硬核讲解 Kubernetes 网络,我不信网工不会看!
15张图超硬核讲解 Kubernetes 网络,我不信网工不会看!
|
网络协议
HCIP第三天ospf星型和全连实验
R1/4/5 使用全连所有接口工作方式为broadcast;DR/BDR将默认自动选举成功 R1
58 0
|
存储 Go 调度
计及调度经济性的光热电站储热容量配置方法【IEEE30节点】(Matlab代码实现)
计及调度经济性的光热电站储热容量配置方法【IEEE30节点】(Matlab代码实现)
|
存储 Go 调度
计及调度经济性的光热电站储热微网模型容量配置方法【IEEE30节点】(Matlab代码实现)
计及调度经济性的光热电站储热微网模型容量配置方法【IEEE30节点】(Matlab代码实现)
|
中间件 应用服务中间件 API
Rack相关知识梳理(一)
一、什么是Rack Rack是ruby应用服务器和Rack应用程序之间的接口, 这里面Ruby应用服务器可以是Webrick、thin等,Rack应用程序可以是rails、Sinatra等(其实 现在主流的ruby的Web框架都是基于Rack的)。在上图中,当用户的请求到达应用服务器时,应用服务器会
576 0
|
弹性计算 运维 Kubernetes
如何才能不被Kubernetes按在地上摩擦?
如何才能不被Kubernetes按在地上摩擦?
如何才能不被Kubernetes按在地上摩擦?
|
Kubernetes 安全 对象存储
大佬愤怒喊话:在大厂做 Kubernetes 开源工作难以晋升
近日,Kubernetes(简称 K8s)圈内大佬 Noah Kantrowitz 连发多条推文抨击“FAANG”科技巨头内部晋升机制对 K8s 全职员工不友好,他指出,“科技大厂们的激励措施正阻止人们全职参与开源贡献,大家的贡献积极性正在放缓。”
189 0
大佬愤怒喊话:在大厂做 Kubernetes 开源工作难以晋升
|
设计模式 中间件 应用服务中间件
Rack相关知识梳理(二)
一、Rack中间件 1、什么是中间件 中间件其实就是Ruby应用服务器和Rack应用程序之间执行的代码 2、一个简单的例子 $LOAD_PATH.unshift(File.dirname(__FILE__)) require 'rack' require 'decorator' my_app = l
277 0
|
Kubernetes 负载均衡 监控
OpenKruise 2021 规划曝光:More than workloads
OpenKruise 是什么?它是阿里云开源的云原生应用自动化管理引擎,也是当前托管在 Cloud Native Computing Foundation (CNCF) 下的 Sandbox 项目。它来自阿里巴巴多年来容器化、云原生的技术沉淀,是阿里内部生产环境大规模应用的基于 Kubernetes 之上的标准扩展组件,一套紧贴上游社区标准、适应互联网规模化场景的技术理念与最佳实践。
OpenKruise 2021 规划曝光:More than workloads