A web framework for Crystal

Crazy Simple

require "raze"

get "/hello" do
  "hello, world"
end

Raze.run

Simply Fast

i
From a MacBook Pro using wrk
~35,000
Express JS
~90,000
Kemal
~120,000
Raze

A Modular, Middleware-Centric Design

Composable "stacks" of middlewares allow for greater modularity. Raze enables and encourages putting more logic inside reusable middlewares rather than putting everything in the route block. Heck, you might not even need a block at all.

# these security middlewares will run before all
# other routes that start with "/api"
get "/api*", [DDoS_Blocker.new, UserAuthenticator.new]


plan_purchase_middlewares = {
  PlanValidator.new,
  PlanPurchaser.new,
  ConfirmationEmailer.new("plan"),
}
get "/api/purchase/plan/:plan_id", *plan_purchase_middlewares do |ctx|
  "purchased plan: #{ctx.params["plan_id"]}"
end


item_purchase_middlewares = {
  ItemValidator.new,
  ItemPurchaser.new,
  ConfirmationEmailer.new("item"),
}
get "/api/purchase/item/:item_id", *item_purchase_middlewares do |ctx|
  "purchased item: #{ctx.params["item_id"]}"
end


# Notice how the ConfirmationEmailer constructor
# expects an arg, which allows us to reuse the same
# middleware for purchasing plans or items
NOTE: The middlewares in the above example are fake, custom middlewares and are not built into Raze

Websocket Channels

Create a websocket channel and broadcast messages to everybody in the channel (a group of sockets).

# allow clients to join a room
ws "/room/:room_id" do |ws, ctx|
  room_id = ctx.params["room_id"]
  user_id = generate_user_id_here

  # get channel by some identifier (creates channel if not exists)
  channel = Raze.ws_channel(room_id)

  # Add socket connection to channel
  channel.add ws

  # broadcast to channel that this user joined
  channel.broadcast(
    {"user_id" => user_id, "msg" => "user joined"}.to_json
  )

  ws.on_message do |msg|
    # broadcast a json message to each websocket in the channel
    channel.broadcast(
      {"user_id" => user_id, "msg" => msg}.to_json
    )
  end

  ws.on_close do
    # remove socket from channel
    channel.remove ws
    # broadcast to any remaining users that this user has left
    channel.broadcast(
      {"user_id" => user_id, "msg" => "user disconnected"}.to_json
    )
  end
end

Sponsors

Qualtrics

Gamma Fi