Skip to content

Interface based on IO subset

Wardrop edited this page Nov 3, 2014 · 1 revision

This wiki article describes a hypothetical server-to-application interface based on an IO object that implements a subset of Ruby's IO class interface. For lack of a better name, we'll call this object the IO object.

The IO object

These are the only methods that need to be implemented on the IO object given to the application.

  • read([length [, outbuf]])
  • write(string)
    • Also aliased as <<
  • close

By limiting the interface to only 3 methods, web server and framework developers can easily abstract, defer, or otherwise re-implement calls to these methods if needed. The interface is compatible with any standard Ruby IO object, which of course includes Sockets, which will likely be the most common object passed to Rack Next applications.

It's anticipated frameworks will implement buffering mechanisms and special interfaces for adding headers as needed. It's also quite likely that higher-level code, such as middleware, will inspect the type of IO object provided and leverage additional functionality provided by different types of IO-like objects.

Application interface

Like Rack, it makes sense to continue using the call method as the interface for applications. It's quite flexible, and makes the interface compatible with Proc objects.

call is expected to take a single argument, which is the IO object. The return value is ignored. Any "result" should be written directly to the IO object.

Unlike the current situation where frameworks are built on-top of the Rack framework, it's anticipated that with Rack Next, frameworks won't be built on top of anything. Instead, they'll work with the raw IO object, leveraging components of the Rack Next library wherever relevant at their convenience.

Loading applications

In Rack, the config.ru file defines via a DSL what endpoint to call; this is achieved using the run method call. In Rack Next, it is up to the server to specify how this is defined, whether it be by command line options or part of a server configuration file. The only two required pieces of information are: what Ruby file to load, and what object to call, represented as a constant.

Conclusion

A simple yet low-level interface like this lowers the barrier of entry for coding closer to the metal, and gets higher-level web developers thinking in terms of streams. It achieves without sacrificing flexibility. Such an interface makes it relatively trivial to implement a compatibility layer for running legacy Rack applications on servers designed for Rack Next.