简体   繁体   English

什么是中间件在Ruby on Rails的上下文中引用?

[英]What is middleware when referenced in the context of Ruby on Rails?

I often hear the term 'middleware' in the context of Ruby on Rails. 我经常在Ruby on Rails的上下文中听到“中间件”这个术语。 What exactly is it? 究竟是什么? Can you provide specific examples? 你能提供具体的例子吗?

Middleware is related to Rack, the standard Ruby API for web applications. 中间件与Rack相关,Rack是Web应用程序的标准Ruby API。 Since Rails applications are Rack applications these days, they apply to both. 由于Rails应用程序目前是Rack应用程序,因此它们适用于两者。

Rack middleware is everything between application servers (Webrick, Thin, Unicorn, Passenger, ...) and the actual application, such as your Rails application. 机架中间件是应用程序服务器(Webrick,Thin,Unicorn,Passenger,...)和实际应用程序(例如Rails应用程序)之间的所有内容。 It is the pipeline between the web application server and the application itself. 它是Web应用程序服务器和应用程序本身之间的管道

The input to a Rack application is an "environment" which contains all the HTTP request details (and more). Rack应用程序的输入是一个“环境”,其中包含所有HTTP请求详细信息(以及更多)。 The output is a HTTP response. 输出是HTTP响应。 Middleware layers are like filters which can modify the input, the output or both. 中间件层就像过滤器一样 ,可以修改输入,输出或两者。 Rails uses middleware to implement some of its features (query caching, cookie stores, http method expansion), but you can add your own. Rails使用中间件来实现它的一些功能 (查询缓存,cookie存储,http方法扩展),但你可以添加自己的。

Rack middleware is an effective way to reuse simple web-related behavior across web applications that use Rack, regardless of the underlying framework. 无论底层框架如何,机架中间件都是在使用Rack的Web应用程序中重用简单的Web相关行为的有效方法。 If a part of your application adds functionality, but is not responsible for a HTTP response , it qualifies as Rack middleware. 如果应用程序的一部分添加了功能,但不负责HTTP响应 ,则它可以作为Rack中间件。

Some examples of things you could implement as Rack middleware include: 您可以作为Rack中间件实现的一些示例包括:

  • HTTP caching (server side and client side) HTTP缓存(服务器端和客户端)
  • Logging 记录
  • Authentication 认证
  • Monitoring 监控
  • HTTP header filtering HTTP标头过滤

See also this SO question . 另见这个问题

Imagine you want to create a caching service. 想象一下,您想要创建一个缓存服务。 This caching service would be app-agnostic so you could use it with many applications. 此缓存服务将是应用程序,因此您可以将它与许多应用程序一起使用。 You'd like to support lots of different web servers too. 您也想支持许多不同的Web服务器。

Notice how it kind of sits in the middle between server and framework? 请注意它在服务器和框架之间的中间位置如何? It's an example of middleware. 这是中间件的一个例子。 It's not application logic and not really low-level network stuff either but provides a service somewhere in between. 它不是应用程序逻辑,也不是真正的低级网络资源,而是在两者之间提供服务。 Some examples are QoS (quality of service), Security, caching, ... 一些例子是QoS(服务质量),安全性,缓存,......

It would be nice if your service supported all n of the popular (and some of the not-so-popular) servers (thin, webrick). 如果您的服务支持流行的所有n(和一些不那么流行的)服务器(薄,使用WEBrick)这将是很好。 If you supported them all more people could use your wonderful software. 如果你支持他们,那么更多的人可以使用你的精彩软件。 You could see that making this happen would be a real drag, you'd need to support each server with special server-specific code. 您可以看到,实现这一点将是一个真正的拖累,您需要使用特殊的服务器特定代码支持每个服务器。

Now that's just half the problem because there are a number of web frameworks too. 现在这只是问题的一半,因为还有许多Web框架。 Rails is the 500-lb gorilla but there are other frameworks, such as Merb and Sinatra . Rails是500磅的大猩猩,但还有其他框架,如Merb和Sinatra Supporting these in your caching service is another m different things to support. 在您的缓存服务支持这些是另一个M不同的东西来支撑。 Now you're supporting nxm different paths. 现在你支持nxm不同的路径。 What a drag. 多么拖累。

Enter Rack . 输入Rack Rack sits between the frameworks and the servers and gives you an interface to code your caching server to. Rack位于框架和服务器之间,为您提供了一个接口,用于为您的缓存服务器编写代码。 If the servers and frameworks support rack, and most do, your service just needs to support the rack interface and you get support for all the frameworks and services rack supports. 如果服务器和框架支持机架,而且大部分都支持,您的服务只需要支持机架接口,您就可以获得对机架支持的所有框架和服务的支持。 (It's a bit like latex compiling to dvi and then turning the dvi into ps, pdf,....). (这有点像乳胶编译到dvi然后将dvi转换为ps,pdf,....)。 You don't need a converter from Merb to WEBrick and another from Sinata to Thin. 您不需要从Merb到WEBrick的转换器以及从Sinata到Thin的转换器。 If your caching service supports rack you're insulated from the differences. 如果您的缓存服务支持机架,则您可以避免差异。

With this "narrow waist", where m-frameworks all come together before branching out to n-servers between the app and server you can also see how it provides a good place to add functionality such as routing, logging, static serving that bypasses the slowness of your interpreted framework, etc. 有了这个“窄腰”,m-frameworks在分支到应用程序和服务器之间的n服务器之前都会聚集在一起你还可以看到它如何提供一个添加功能的好地方,例如路由,日志记录,静态服务绕过解释框架的缓慢等

Rails middleware allows you to catch request or response before it reaches Rails, and modify it. Rails中间件允许您在到达Rails之前捕获请求或响应,并对其进行修改。 (You are in the middle between Rack and Rails). (你是在机架和Rails之间的中间 )。 For example, you can take every response that returns an "image/png" mime-type, and add watermark to it before letting it move onto Rack for serving. 例如,您可以使用返回“image / png”mime类型的每个响应,并在将其移动到Rack以进行服务之前为其添加水印。 Or you can filter out requests that you don't like for some reason (unauthorized, don't have a header) and never let them hit rails at all. 或者你可以过滤掉你不喜欢的请求,因为某些原因(未经授权,没有标题),永远不要让它们碰到铁轨。 Or you can add a header to an incoming request before passing it onto rails. 或者,您可以在将传递请求传递到rails之前为其添加标头。 Or you can take response coming from rails, and if it's "text/html" you can compress html (remove whitespace, etc) before passing on to the output. 或者您可以从rails获取响应,如果它是“text / html”,您可以在传递到输出之前压缩html(删除空格等)。 (I was experimenting with it in http://github.com/maxim/html_press ) (我在http://github.com/maxim/html_press上试验过它)

These little apps are plenty and are plugged in as "middleware". 这些小应用程序很多,并作为“中间件”插入。

Explanation to a 4 year old: 对4岁的解释:

Do you remember the game: "Chinese whispers" that you played as a kid? 你还记得这个游戏:你小时候玩过的“中国人低语”吗? (no racism intended - that was actually what the game was called in my day). (没有种族主义意图 - 这实际上是我今天所称的游戏)。 You want to tell your friend - who sits at the other end of the line, a special message. 你想告诉你的朋友 - 坐在另一端的朋友,这是一条特别的信息。 but you can't tell him or her directly: you must pass your message from person to person until it finally reaches him or her. 但是你不能直接告诉他或她:你必须将你的信息从一个人传到另一个人,直到它最终到达他或她。

But more often that not you'll find that changes to the message happen as it goes through the chain, till it reaches the end point. 但更常见的是,你不会发现消息的变化发生在链条中,直到达到终点。 For example: 例如:

  1. Originator : “You will always remember this as the day that you almost caught Captain Jack Sparrow.” 创始人 :“你将永远记住这一天,你几乎抓住了杰克斯派洛船长。”
  2. Person 1 - passes on: “You will always remember the day that you almost caught Captain Jack Sparrow.” 第1个人 - 传递:“你将永远记住你几乎抓住杰克斯派洛船长的那一天。”
  3. Person 2 - passes on: “You will always remember the day that you almost caught Captain Jack Sparrow.” 第二个人 - 传递:“你将永远记住你几乎抓住杰克斯派洛船长的那一天。”
  4. Person 3 - passes on: “You will remember the day you caught Captain Jack Sparrow.” 第3个人 - 传递:“你会记得你抓住杰克斯派洛船长的那一天。”
  5. Person 4 - passes on: “You will remember Captain Jack Sparrow.” 第4个人 - 传递:“你会记得Jack Sparrow上尉。”
  6. Final Message received : “Remember” 收到最后消息 :“记住”

Middleware are basically the people in between you, the originator of the message, and the final message that was recieved: notice how they can change or filter the message? 中间件基本上是您之间的人,消息的发起者,以及收到的最终消息:注意他们如何更改或过滤消息? That's kinda what middleware is all about in a nutshell. 简而言之,这就是中间件的全部内容。 Granted the anology is strained, but hopefully that will give you a basis on which to understand the more technical answers above. 虽然这种神学很紧张,但希望这能为你提供一个理解上述技术答案的基础。

Having a look at CodeRack can help understand what some of the possibilities are. 查看CodeRack可以帮助理解一些可能性。 Now when you ask that you often hear of it in the context of Ruby on Rails, are you more generally asking what middleware is? 现在当你要求你经常在Ruby on Rails的上下文中听到它时,你是否更普遍地问中间件是什么?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM