DEV Community

Sean Walker
Sean Walker

Posted on • Edited on

Website routing made simple and easy

I was kidding myself for a long time. I thought of myself as an engineer, I was making complex billion user web apps, I was ENGINEERING the front end and the back end, of course I was. Except I wasn't.

I make websites.

When I finally came around and saw myself how other people see me, I reached website maker enlightenment. I stopped using complex js frameworks, complex backend api tech, I quit graphql, I quit REST APIs, I quit doing stupid stuff, and I started finishing projects.

I want you to finish your projects too, and the first step is to dump those complex frontend frameworks, and maybe embrace the simplicity of clojure.

How exactly is routing made simple or easy. WTF does that even mean?

I'll show you. Here's a route all by itself

[:get "/" `home]
Enter fullscreen mode Exit fullscreen mode

Here's two routes

[[:get "/" `home]
 [:get "/@:name" `profile]]
Enter fullscreen mode Exit fullscreen mode

This is a route in coast on clojure

(ns your-project
  (:require [coast.delta :as coast]))

(defn home [request]
  {:status 200
   :headers {"Content-Type" "text/html"}
   :body "Hello world!"})

(def routes [[:get "/" `home]])

(def app (coast/app routes))

(app {:request-method :get :uri "/"}) ; => Hello world!
Enter fullscreen mode Exit fullscreen mode

Routes in coast are a vector of vectors, the routes that are on top get matched first.

(defn hello [request]
  {:status 200
   :headers {"Content-Type" "text/html"}
   :body "hello world!"})

(defn goodbye [request]
  {:status 200
   :headers {"Content-Type" "text/html"}
   :body "goodbye, cruel world!"})

(def routes [[:get "/" `hello]
             [:get "/" `goodbye]])

(def app (coast/app routes))

(app {:request-method :get :uri "/"}) ; => hello world!
Enter fullscreen mode Exit fullscreen mode

If you don't want to write vectors all day, you can use coast's route functions

(ns routes
  (:require [coast.router :refer [get post put delete wrap-routes]])
  (:refer-clojure :exclude [get]))

(defn home [request]
  "welcome!")

(defn profile [request]
  (str "hello, " (get-in request [:params :name])))

(def routes (-> (get "/" `home)
                (get "/@:name" `profile)))

(def app (coast/app routes))
Enter fullscreen mode Exit fullscreen mode

Here's a more complete example for something like auth with buddy

(ns routes
  (:require [coast.router :refer [get post put delete wrap-routes]]
            [coast.responses :as res]
            [controllers.home :as c.home]
            [controllers.users :as c.users]
            [buddy.auth])
  (:refer-clojure :exclude [get]))

(defn wrap-auth [handler]
  (fn [request]
    (if (buddy.auth/authenticated? request)
      (handler request)
      (res/forbidden
        "I'm sorry dave, I can't let you do that."))))

(def auth (-> (get "/users/:id" `c.users/show)
              (wrap-routes middleware/wrap-auth)))

(def public (get "/" `c.home/index))

(def routes (concat public auth))
Enter fullscreen mode Exit fullscreen mode

Routing in coast on clojure is meant to be easy and meant to be easy to understand. Hopefully I've given you a glimpse into just one aspect of how making websites, not complex over-engineered front end heavy web apps can be made simple and easy.

If you're picking up what I'm putting down, give coast on clojure a try!

Top comments (0)