class Onyx::HTTP::Middleware::Router

Overview

Routes a request's path, then updates extracted path params to ::HTTP::Request#path_params, executes the matching proc and calls the next handler if it's present.

Raises Router::NotFound if no route is found for the URL path, Router::MethodNotAllowed if the request method is not allowed or Router::UpgradeRequired if the endpoint requires websocket protocol.

router = Onyx::HTTP::Middleware::Router.new do |r|
  r.get "/" do |env|
    env.response << "Hello world!"
  end

  r.ws "/" do |socket, env|
    socket.on_message do |message|
      # ...
    end
  end

  r.on "/users" do
    r.post "/", Endpoint::User::Create
    r.get "/:id", Endpoint::User::Get
  end
end

renderer = Onyx::HTTP::Middleware::Renderer.new
rescuer = Onyx::HTTP::Middleware::Rescuer::Standard(Exception).new(renderer)
server = Onyx::HTTP::Server.new([rescuer, router, renderer])

Included Modules

Defined in:

onyx-http/middleware/router/bad_request.cr
onyx-http/middleware/router/method_not_allowed.cr
onyx-http/middleware/router/not_found.cr
onyx-http/middleware/router/upgrade_required.cr
onyx-http/middleware/router/websocket_handler.cr
onyx-http/middleware/router.cr

Constructors

Instance Method Summary

Constructor Detail

def self.new(&block) #

Initialize a new router and yield it. You should then define routes in the &block.

# The simplest router
router = Router.new do |r|
  r.get "/" do |env|
    env.response << "Hello world!"
  end
end

[View source]

Instance Method Detail

def call(context) #

Lookup for a route, update context.request.path_params and call the matching proc, raising RouteNotFound otherwise. Calls the next handler if it's present.


[View source]
def delete(path, endpoint : HTTP::Endpoint.class) #

Draw a route for path with DELETE calling endpoint. See Endpoint. If a View instance is returned, then the ::HTTP::Server::Response#view is set to this view.

router = Router.new do |r|
  r.delete "/bar", MyEndpoint
end

[View source]
def delete(path, &proc : HTTP::Server::Context -> View | UNDERSCORE) #

Draw a route for path with DELETE method. If a View instance is returned, then the ::HTTP::Server::Response#view is set to this view.

router = Router.new do |r|
  r.delete "/bar" do |env|
    env.response << "Hello from DELETE /bar!"
  end
end

[View source]
def get(path, &proc : HTTP::Server::Context -> View | UNDERSCORE) #

Draw a route for path with GET method. If a View instance is returned, then the ::HTTP::Server::Response#view is set to this view.

router = Router.new do |r|
  r.get "/bar" do |env|
    env.response << "Hello from GET /bar!"
  end
end

[View source]
def get(path, endpoint : HTTP::Endpoint.class) #

Draw a route for path with GET calling endpoint. See Endpoint. If a View instance is returned, then the ::HTTP::Server::Response#view is set to this view.

router = Router.new do |r|
  r.get "/bar", MyEndpoint
end

[View source]
def head(path, &proc : HTTP::Server::Context -> View | UNDERSCORE) #

Draw a route for path with HEAD method. If a View instance is returned, then the ::HTTP::Server::Response#view is set to this view.

router = Router.new do |r|
  r.head "/bar" do |env|
    env.response << "Hello from HEAD /bar!"
  end
end

[View source]
def head(path, endpoint : HTTP::Endpoint.class) #

Draw a route for path with HEAD calling endpoint. See Endpoint. If a View instance is returned, then the ::HTTP::Server::Response#view is set to this view.

router = Router.new do |r|
  r.head "/bar", MyEndpoint
end

[View source]
def namespace : Array(String) #

[View source]
def on(path, methods : Array(String), &proc : HTTP::Server::Context -> View | UNDERSCORE) #

Draw a route for path and methods. If a View instance is returned, then the ::HTTP::Server::Response#view is set to this view.

router = Router.new do |r|
  r.on "/foo", methods: %w(get post) do |env|
    env.response << "Hello from #{env.request.method} /foo!"
  end
end

[View source]
def on(namespace : String? = nil, &block : self -> ) #

Yield self with a namespace. The namespace can also be empty or nil, so you can prettify your router blocks.

router = Router.new do |r|
  r.on "/users" do
    r.post "/"   # Resulting route is "POST /users/"
    r.get "/:id" # Resulting route is "GET /users/:id"
  end
end

[View source]
def on(path, methods : Array(String), endpoint : HTTP::Endpoint.class) #

Draw a route for path and methods calling endpoint. See Endpoint. If a View instance is returned, then the ::HTTP::Server::Response#view is set to this view.

router = Router.new do |r|
  r.on "/foo", methods: %w(get post), MyEndpoint
end

[View source]
def options(path, endpoint : HTTP::Endpoint.class) #

Draw a route for path with OPTIONS calling endpoint. See Endpoint. If a View instance is returned, then the ::HTTP::Server::Response#view is set to this view.

router = Router.new do |r|
  r.options "/bar", MyEndpoint
end

[View source]
def options(path, &proc : HTTP::Server::Context -> View | UNDERSCORE) #

Draw a route for path with OPTIONS method. If a View instance is returned, then the ::HTTP::Server::Response#view is set to this view.

router = Router.new do |r|
  r.options "/bar" do |env|
    env.response << "Hello from OPTIONS /bar!"
  end
end

[View source]
def patch(path, &proc : HTTP::Server::Context -> View | UNDERSCORE) #

Draw a route for path with PATCH method. If a View instance is returned, then the ::HTTP::Server::Response#view is set to this view.

router = Router.new do |r|
  r.patch "/bar" do |env|
    env.response << "Hello from PATCH /bar!"
  end
end

[View source]
def patch(path, endpoint : HTTP::Endpoint.class) #

Draw a route for path with PATCH calling endpoint. See Endpoint. If a View instance is returned, then the ::HTTP::Server::Response#view is set to this view.

router = Router.new do |r|
  r.patch "/bar", MyEndpoint
end

[View source]
def post(path, endpoint : HTTP::Endpoint.class) #

Draw a route for path with POST calling endpoint. See Endpoint. If a View instance is returned, then the ::HTTP::Server::Response#view is set to this view.

router = Router.new do |r|
  r.post "/bar", MyEndpoint
end

[View source]
def post(path, &proc : HTTP::Server::Context -> View | UNDERSCORE) #

Draw a route for path with POST method. If a View instance is returned, then the ::HTTP::Server::Response#view is set to this view.

router = Router.new do |r|
  r.post "/bar" do |env|
    env.response << "Hello from POST /bar!"
  end
end

[View source]
def put(path, endpoint : HTTP::Endpoint.class) #

Draw a route for path with PUT calling endpoint. See Endpoint. If a View instance is returned, then the ::HTTP::Server::Response#view is set to this view.

router = Router.new do |r|
  r.put "/bar", MyEndpoint
end

[View source]
def put(path, &proc : HTTP::Server::Context -> View | UNDERSCORE) #

Draw a route for path with PUT method. If a View instance is returned, then the ::HTTP::Server::Response#view is set to this view.

router = Router.new do |r|
  r.put "/bar" do |env|
    env.response << "Hello from PUT /bar!"
  end
end

[View source]
def ws(path, &proc : ::HTTP::WebSocket, HTTP::Server::Context -> ) #

Draw a "ws://" route for path.

A request is currently determined as websocket by "Upgrade": "Websocket" header.

router = Router.new do |r|
  r.ws "/foo/:bar" do |socket, env|
    socket.send("Hello WS!")
  end
end

[View source]
def ws(path, channel : T.class) : Nil forall T #

Draw a "ws://" route for path binding channel. See Channel. A request is currently determined as websocket by "Upgrade": "Websocket" header.

router = Router.new do |r|
  r.ws "/foo", MyChannel
end

[View source]