a micro web framework/internal DSL to wire Ring handlers and middlewares
Alternatives To Moustache
Project NameStarsDownloadsRepos Using ThisPackages Using ThisMost Recent CommitTotal ReleasesLatest ReleaseOpen IssuesLicenseLanguage
11 years ago4February 10, 20205Clojure
a micro web framework/internal DSL to wire Ring handlers and middlewares
2 years ago6apache-2.0JavaScript
A url shortener of your own, using Netlify redirect rules
Using Passport69
6 years ago9JavaScript
How do I use Passport with my Sails app?
Mern Stack Front To Back44
2 years ago22JavaScript
[Brad Traversy] MERN Stack Front To Back: Full Stack React, Redux & Node.js [ENG, 2018]
Learning Go39
3 years agomit
List of concepts and code snippets that would help in learning Golang and apply in Web Development 🎉
Falcor Saddle21127 years ago6January 03, 20173mitJavaScript
Model route generation for Netflix Falcor – giddyup!
8 years agoJavaScript
Declarative, data-driven apps with React and Meteor
Network Pulse Api10
a year ago31mpl-2.0Python
API for the Network-Pulse project
a year ago3July 29, 20204mitElixir
Passwordless Strategy for Überauth
Angular4 Crud Node Mongoose Bootstrap48
6 years agoTypeScript
This is a simple Clean Code CRUD, based in NodeJS&Mongoose/MongoDB(Server), Angular 4&Bootstrap 4(Frontend). Also iit has validation forms, services, routes and more.
Alternatives To Moustache
Select To Compare

Alternative Project Comparisons


  (app ["hi"] {:get "Hello World!"})

Moustache is a micro web framework/internal DSL to wire Ring handlers and middlewares.

How micro is it?

Well, there’s only one macro you need to know: app.

Every other public var is public only because app needs it in its expansion.


See syntax.html


The app macro

A (app ...) form returns a Ring application (handler).

There’s currently four usages of app:

  • to wrap a Ring handler,
  • to define routes,
  • to dispatch on HTTP methods
  • and to render plain text.

Wrapping an existing Ring handler

  (app my-handler) ; identity, returns my-handler

You can simply wrap a handler into middlewares:

(middleware2 arg)
; equivalent to (→ my-handler (middleware2 arg) middleware1)
; ie (middleware1 (middleware2 my-handler arg))

Note that every usage of app supports middleware-wrapping.



With Moustache you don’t write routes as encoded uri (eg "/Thank%20you%20Mario/But%20our%20princess%20is%20in%20another%20castle"), you write vectors of decoded segments (eg ["Thank you Mario" "But our princess is in another castle"]).

  (app ["foo"] my-handler) ; will route requests to "/foo" to my-handler
  (app ["foo" ""] my-handler) ; will route requests to "/foo/" to my-handler
  (app ["foo" "bar"] my-handler) ; will route requests to "/foo/bar" to my-handler
  (app ["foo" &] my-handler) ; will route requests to "/foo", "/foo/", "/foo/bar" and "/foo/bar/baz/" to my-handler (and will chop "/foo" off from the uri)
  (app ["foo" name] my-handler) ; will route requests to "/foo/", "/foo/bar" to my-handler and bind @name@ (a local) to the matched segment (eg "" or "bar")
  (app ["foo" x & xs] my-handler) ; "/foo/bar/baz/bloom" will bind x to bar and xs to ["baz" "bloom"]

You can catch all URIs with the route [&]. If you don’t provide a handler for [&] and there’s no handler for a request Moustache sends a 404 (not found) response.

Route validation/destructuring

  (defn integer [s]
   "returns nil if s does not represent an integer
      (Integer/parseInt s)
      (catch Exception e)))

  (app ["order" [id integer]] my-handler) ; for "/order/134" @id@ will be bind to 134 (not "134"), this route will not match "/order/abc".
  (app ["agenda" [[_ year month day] #"(\d{4})-(\d{2})-(\d{2})"]] 
    {:get [month "-" day "-" year " agenda"]})

Fall through

The routes are tried in order until one route matches the request uri and the associated handler does not return nil.

That’s why:

    ["foo" &] (app ["bar"] handler1)
    ["foo" "baz"] handler2)

returns a 404 for /foo/baz: the nested app form returns a 404 for /baz and this 404 bubbles up.

You can prevent such behavior by writing:

    ["foo" &] (app 
                ["bar"] handler1
                [&] pass)
    ["foo" "baz"] handler2)

Method dispatch

    :get handler-for-get
    :post handler-for-post)

You can add a catch-all using the :any keyword.

If you don’t specify a handler for :any, Moustache sends a 405 response (method not allowed).


When the right-hand form of a route or of a method dispatch is a (app ...) form, you can write the form as a vector: (app ["foo" &] (app ["bar"] handler)) can be shortened to (app ["foo" &] [["bar"] handler]).

Besides when the right-hand form is a method dispatch without middlewares you can write the form as a map: (app ["foo"] (app :get handler)) can be shortened to (app ["foo"] {:get handler}).

Popular Form Projects
Popular Routes Projects
Popular User Interface Components Categories

Get A Weekly Email With Trending Projects For These Categories
No Spam. Unsubscribe easily at any time.