Middlewares

Middleware = Raze's baby's mama

In Raze, middlewares handlers are defined (and stored) directly with the route. They are not globally scoped so you don't need to put logic inside the middleware itself for route matching or filtering. Instead, just add the middleware to the appropriate routes and forget about it.

Middleware Usage

If you wanted to add a custom UserAuth middleware to your get "/user" route, its as simple as doing the following:

get "/user", UserAuth.new

...or with a block if you're feeling saucy:

get "/user", UserAuth.new do |ctx|
  "user authenticated"
end

You can add them to a route as normal arguments, like so:

get "/user", DDoS_Blocker.new, UserAuth.new, UserEmailer.new do |ctx|
  "user authenticated"
end

Or as an array:

get "/user", [DDoS_Blocker.new, UserAuth.new, UserEmailer.new] do |ctx|
  "user authenticated"
end

Believe it or not, this modular middleware design was the inspiration for creating Raze in the first place.

Creating Middlewares

Custom middleware, or handlers, are classes that inherit from Raze::Handler. You need to define a call method that expects two arguments—the context (ctx) and the callback (done) for when the middleware finishes.

class MyCustomMiddleware < Raze::Handler
  def call(ctx, done)
    puts "hello from my custom middleware!"
    done.call
  end
end
Don't forget to `call` the done argument! (e.g. `done.call`)

The Middleware Philosophy

Middlewares are Raze's attempt at encouraging or enabling a certain application design, but you are not required to use them. Raze encourages you to write all of the utillity functions and classes you would normally write for your application, but then create middleware wrapper around lots of your code. The middleware is where you handle the server related logic (e.g. how to respond to the client if a database query fails).

For example, you write a method for querying a db for a user. That would be a complete method in a class somewhere (not in a middleware). Now you can use a single middleware to wrap that functionality and write the logic for how to respond to the client should the query fail.