Patchbay is a minimal web framework designed to let you add HTTP APIs to existing Ruby-based applications with minimum effort and frustration:
# test.rb require 'patchbay' require 'json' class MyInterface < Patchbay attr_accessor :rest_of_app get '/' do render :json => rest_of_app.some_data_structure.to_json end end class RestOfApp def some_data_structure { 'a' => 'b', 'c' => 'd' } end end rest_of_app = RestOfApp.new interface = MyInterface.new interface.rest_of_app = rest_of_app interface.run(:Host => '::', :Port => 3000)
A Patchbay interface is a class derived from the Patchbay class. Routes are defined in the interface using the get, put, post, and delete class methods. Each of these takes a block that is invoked when an incoming request matches the route.
Routes can contain symbols representing variable parameters:
get '/say/:something' { render :html => params[:something] }
The parameters are accessed via the “params” instance method, which returns a hash of all parameters interpolated from the URL. Query strings are not supported (yet).
To start serving up the API, instantiate your interface then call its “run” method. This can be from a separate thread of control, and probably should be if your application is doing other tasks in the background.
The render instance method sets the response content. For example,
render :html => '<html><body>Hello World</body></html>'
sends the greeting to the browser with a content type of ‘text/html’. Content types are guessed intelligently using Rack::Mime, so things like
render :json => '{ :a => "b" }'
and
render :jpg => some_jpeg_data
should be supported.
The render method supports setting the response status code:
render :error => 404, :html => your_404_page
Files can be sent instead of rendering some string content:
send_file '/path/to/file'
Note that no protection is provided against directory-traversal when using send_file. The files_dir facility should be used for serving static files.
To serve up static files alongside your interface, set the files_dir attribute on your interface class:
class MyInterface self.files_dir = "/path/to/static/files" ... routes and handlers ... end
The path may be either absolute or relative. If no route is matched by an incoming request, Patchbay will try to find a matching file in the path given. Requested filenames are canonicalized using File.realpath and checked that they fall within the path provided. This prevents directory-traversal attacks, but also will result in errors if symlinks within the static files path point to an outside location.
Interface instances can have attributes and instance variables, like instances of any other Ruby class. This enables a Patchbay interface to be connected to any application objects with minimum effort. The attributes, instance variables, and instance methods are accessible to the request handlers.
An interface instance is a valid Rack application, so Patchbay works with servers including WEBrick, Mongrel, and Thin. There is an example Rack configuration in the examples directory.
Copyright © 2011 by Andrew H. Armenia.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.