All Projects → askonomm → ruuter

askonomm / ruuter

Licence: MIT license
A zero-dependency HTTP router

Programming Languages

clojure
4091 projects

Labels

Projects that are alternatives of or similar to ruuter

easytcp
✨ 🚀 EasyTCP is a light-weight TCP framework written in Go (Golang), built with message router. EasyTCP helps you build a TCP server easily fast and less painful.
Stars: ✭ 416 (+629.82%)
Mutual labels:  router
Android-XRouter
This is a lightweight and simple routing framework that provides jump routing and method routing.
Stars: ✭ 19 (-66.67%)
Mutual labels:  router
use-router-machine
Router state-machine hook, powered by XState (DEPRECATED).
Stars: ✭ 11 (-80.7%)
Mutual labels:  router
fast-route
PSR-15 middleware to use FastRoute
Stars: ✭ 91 (+59.65%)
Mutual labels:  router
Parrot
Web router specially designed for building SPAs using Meteor
Stars: ✭ 75 (+31.58%)
Mutual labels:  router
use-react-router-breadcrumbs
tiny, flexible, hook for rendering route breadcrumbs with react-router v6
Stars: ✭ 170 (+198.25%)
Mutual labels:  router
es6-router
🌐 Simple client side router built in ES6
Stars: ✭ 16 (-71.93%)
Mutual labels:  router
openwrt
OpenWrt Stable 1907 with lean's package
Stars: ✭ 55 (-3.51%)
Mutual labels:  router
Stime
基于Vue-cli3(Vue+Vue-router)构建的单页单栏Typecho主题,全站Ajax+类Pjax(Vue-router)无刷新,自适应适配移动设备
Stars: ✭ 29 (-49.12%)
Mutual labels:  router
http-multiserver.cr
Mount multiple web applications 🚦
Stars: ✭ 23 (-59.65%)
Mutual labels:  router
routex.js
🔼 Alternative library to manage dynamic routes in Next.js
Stars: ✭ 38 (-33.33%)
Mutual labels:  router
qlevar router
Manage you project Routes. Create nested routes. Simply navigation without context to your pages. Change only one sub widget in your page when navigating to new route.
Stars: ✭ 51 (-10.53%)
Mutual labels:  router
neteng-roadmap
Network Engineering at Scale Roadmap/Landscape
Stars: ✭ 53 (-7.02%)
Mutual labels:  router
journey
A conductor routing helper library
Stars: ✭ 35 (-38.6%)
Mutual labels:  router
middle-router
Route urls on both client and server through middleware
Stars: ✭ 33 (-42.11%)
Mutual labels:  router
RoundedLayout
This is a library that has a rounded cut of View, support whether the specified corners are cropped and add a custom Border, and add a shadow support from API 9, which is based on FrameLayout, that is, His Child can be any View, the current library or preview version, if you encounter problems in the process can submit issue or pr.
Stars: ✭ 24 (-57.89%)
Mutual labels:  router
orion
A Crystal router
Stars: ✭ 115 (+101.75%)
Mutual labels:  router
Computer-Networks
GBN and SR simulation, Distance Vector Algorithm Simulation
Stars: ✭ 21 (-63.16%)
Mutual labels:  router
organiser
An organic web framework for organized web servers.
Stars: ✭ 58 (+1.75%)
Mutual labels:  router
RouteNow
RouteNow is a small fast library ⚡ that will help you in developing a SinglePage Application without any dependencies like jQuery, AngularJs, vue.js or any of those bulky frameworks.
Stars: ✭ 17 (-70.18%)
Mutual labels:  router

Ruuter

A tiny, zero dependency HTTP router for Clojure(Script) that operates with a simple data structure where each route is a map inside a vector. Yup, that's it. No magic, no bullshit.

Installation

Clojars Project

Usage

Setting up

Require the namespace ruuter.core and then pass your routes to the route function along with the current request map, like this:

(ns myapp.core
  (:require [ruuter.core :as ruuter]))

(def routes [{:path "/"
              :method :get
              :response {:status 200
                         :body "Hi there!"}}])

(def request {:uri "/"
              :request-method :get})

(ruuter/route routes request) ; => {:status 200
                              ;     :body "Hi there!"}

This will attempt to match a route with the request map and return the matched route' response. If no route was found, it will attempt to find a route that has a :path that is :not-found, and return its response instead. But if not even that route was found, it will simply return a built-in 404 response instead.

Note that the request-method doesn't have to be a keyword, it can be anything that your HTTP server returns. But it does have to be called request-method for the router to know where to look for.

Setting up with http-kit

Now, obviously on its own the router is not very useful as it needs an actual HTTP server to return the responses to the world, so here's an example that uses http-kit:

(ns myapp.core
  (:require [ruuter.core :as ruuter]
            [org.httpkit.server :as http]))

(def routes [{:path "/"
              :method :get
              :response {:status 200
                         :body "Hi there!"}}
             {:path "/hello/:who"
              :method :get
              :response (fn [req]
                          {:status 200
                           :body (str "Hello, " (:who (:params req)))})}])

(defn -main []
  (http/run-server #(ruuter/route routes %) {:port 8080}))

Setting up with Ring + Jetty

Ring + Jetty set-up is almost identical to the one of http-kit, and looks like this:

(ns myapp.core
  (:require [ruuter.core :as ruuter]
            [ring.adapter.jetty :as jetty]))

(def routes [{:path "/"
              :method :get
              :response {:status 200
                         :body "Hi there!"}}
             {:path "/hello/:who"
              :method :get
              :response (fn [req]
                          {:status 200
                           :body (str "Hello, " (:who (:params req)))})}])

(defn -main []
  (jetty/run-jetty #(ruuter/route routes %) {:port 8080}))

Setting up with Babashka

You can also use Ruuter with Babashka, by using the built-in http-kit server, for example. Either add the dependency in your bb.edn file or if you want to make the whole thing one-file-rules-them-all, then load it in with deps/add-deps, like below:

#!/usr/bin/env bb

(deps/add-deps '{:deps {org.clojars.askonomm/ruuter {:mvn/version "1.2.2"}}})

(require '[org.httpkit.server :as http]
         '[babashka.deps :as deps]
         '[ruuter.core :as ruuter])

(def routes [{:path "/"
              :method :get
              :response {:status 200
                         :body "Hi there!"}}])

(http/run-server #(ruuter/route routes %) {:port 8082})

@(promise)

Creating routes

Like mentioned above, each route is a map inside of a vector - the order is important only in that the route matcher will return the first result it finds according to :path.

Each route consists of three items:

:path

A string path starting with a forward slash describing the URL path to match.

To create parameters from the path, prepend a colon (:) in front of a path slice like you would with a Clojure keyword. For example a string such as /hi/:name would match any string that matches the \/hi\/.* regex. The :name itself will then be available with its value from the request passed to the response function, like this:

(fn [req]
  (let [name (:name (:params req))]
    {:status 200
     :body (str "Hi, " name)}))

Additionally, you may want to use an optional parameter, in which case you'd want to add a question mark to the end of it, like /hi/:name?, which will match the \/hi\/?.*? regex, meaning that the previous forward slash is optional, and what comes after that is also optional.

:method

The HTTP method to listen for when matching the given path. This can be whatever the HTTP server uses. For example, if you're using http-kit for the HTTP server then the accepted values are:

  • :get
  • :post
  • :put
  • :delete
  • :head
  • :options
  • :patch

:response

The response can be a direct map, or a function returning a map. In case of a function, you will also get passed to you the request map that the HTTP server returns, with added-in :params that contain the values for the URL parameters you use in your route's :path.

Thus, a :response can be a map:

{:status 200
 :body "Hi there!"}

Or a function returning a map:

(fn [req]
  {:status 200
   :body "Hi there!"})

What the actual map can contain that you return depends again on the HTTP server you decided to use Ruuter with. The examples I've noted here are based on http-kit & ring + jetty, but feel free to make a PR with additions for other HTTP servers.

Changelog

1.2.2

  • Fixed an issue where CLJS compilation would fail because of the (:gen-class) that is JVM-only.

  • Tests are now runnable for CLJS as well, via clojure -Atest.

1.2.1

  • Fixed an issue with regex parsing. Sorry about that.

1.2.0

  • Implemented optional route parameters, so now you can do paths like /hi/:name? in your routes, and it would match the route even if the :name is not present. All you have to do is add a question mark to the parameter, and that's it.

  • Changed Ruuter from a .clj file to a .cljc file, so it would also work with ClojureScript. Although it would probably require a more hands-on set-up than just a drop-in to an HTTP server like http-kit or ring + jetty, there is no reason that the router itself wouldn't work as it does not rely on any platform-specific code.

  • Ruuter also works with Babashka, and I've created a "Setting up with Babashka" section in this README to show that.

1.1.0

  • Made Ruuter server-agnostic, which means now it really is just a router and nothing else, and can thus be used with just about any HTTP server you can throw at it. It also means there are now zero dependencies! ZERO!
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].