jester

A sinatra-like web framework for Nimrod.

Homepage: https://github.com/dom96/jester

Platform: Nimble

Language: Nimrod

License: MIT

Install: nimble install jester


Jester

The sinatra-like web framework for Nim. Jester provides a DSL for quickly creating web applications in Nim.

Note: Jester requires Nim version 0.10.0.

# example.nim
import jester, asyncdispatch, htmlgen
routes:
 get "/":
 resp h1("Hello world")
runForever()

Compile and run with:

nim c -r example.nim

View at: localhost:5000

Routes

routes:
 get "/":
 # do something here.

All routes must be inside a routes block.

Routes will be executed in the order that they are declared. So be careful when halting.

Currently only get and post routes are available.

The route path may contain a special pattern or just a static string. Special patterns are almost identical to Sinatra's, the only real difference is the use of @ instead of the :.

get "/hello/@name":
 # This matches "/hello/fred" and "/hello/bob".
 # In the route ``@"name"`` will be either "fred" or "bob".
 # This can of course match any value which does not contain '/'.
 resp "Hello " & @"name"

The patterns in Jester are currently a bit more limited, there is no wildcard patterns.

You can use the '?' character to signify optional path parts.

get "/hello/@name?":
 # This will match what the previous code example matches but will also match
 # "/hello/".
 if @"name" == "":
 resp "No name received :("
 else:
 resp "Hello " & @"name"

In this case you might want to make the leading '/' optional too, you can do this by changing the pattern to "/hello/?@name?". This is useful because Jester will not match "/hello" if the leading '/' is not made optional.

Regex

Regex can also be used as a route pattern. The subpattern captures will be placed in request.matches when a route is matched. For example:

get re"^\/([0-9]{2})\.html$":
 resp request.matches[0]

This will match URLs of the form /15.html. In this case request.matches[0] will be 15.

Conditions

Jester supports conditions, however they are limited to a simple cond template.

routes:
 get "/@name":
 cond @"name" != "daniel"
 # ``cond`` will pass execution to the next matching route if @"name" is not
 # "daniel".
 resp "Correct, my name is daniel."
 get "/@name":
 # This will be the next route that is matched.
 resp "No, that's not my name."

Return values

Route bodies all have an implicit request object. This object is documented in jester.nim and documentation can be generated by executing nim doc jester.nim.

Returning a response from a route should be done using one of the following functions:

  • One of the resp functions.
  • By setting body, headers and/or status and calling return.
  • redirect function
  • attachment function

There might be more. Take a look at the documentation of jester.nim for more info.

Manual routing

It is possible not to use the routes macro and to do the routing yourself.

You can do this by writing your own match procedure. Take a look at example2 for an example on how to do this.

Static files

By default Jester looks for static files in ./public. This can be overriden using the setStaticDir function. Files will be served like so:

./public/css/style.css -> http://example.com/css/style.css

Cookies

Cookies can be set using the setCookie function.

get "/":
 # Set a cookie "test:value" and make it expire in 5 days.
 setCookie("test", @"value", daysForward(5))

They can then be accessed from the request.cookies PStringTable.

Request object

The request object holds all the information about the current request. You can access it from a route using the request variable. It is defined as:

PRequest* = ref object
 params*: StringTableRef ## Parameters from the pattern, but also the
 ## query string.
 matches*: array[MaxSubpatterns, string] ## Matches if this is a regex
 ## pattern.
 body*: string ## Body of the request, only for POST.
 ## You're probably looking for ``formData``
 ## instead.
 headers*: StringTableRef ## Headers received with the request.
 ## Retrieving these is case insensitive.
 formData*: TMultiData ## Form data; only present for
 ## multipart/form-data
 port*: int
 host*: string
 appName*: string ## This is set by the user in ``run``, it is
 ## overriden by the "SCRIPT_NAME" scgi
 ## parameter.
 pathInfo*: string ## This is ``.path`` without ``.appName``.
 secure*: bool
 path*: string ## Path of request.
 cookies*: StringTableRef ## Cookies from the browser.
 ip*: string ## IP address of the requesting client.
 reqMeth*: TReqMeth ## Request method, eg. HttpGet, HttpPost
 settings*: PSettings

Examples

Github service hooks

The code for this is pretty similar to the code for Sinatra given here: http://help.github.com/post-receive-hooks/

import jester, asyncdispatch, json
routes:
 post "/":
 var push = parseJson(@"payload")
 resp "I got some JSON: " & $push
runForever()
веселые картинки развлекательные гифки интресные факты смешные видео смешные истории из соцсетей

GitHub Repository

dom96/jester dom96/jester

A sinatra-like web framework for Nim.

Language: Nimrod

Created: April 29, 2012 23:18

Last updated: March 28, 2015 02:07

Last pushed: March 27, 2015 19:54

Size: 535 KB

Stars: 198

Forks: 17

Watchers: 15

Open issues: 6

Top Contributors

Dominik Picheta Jason Livesay Moe Andreas Rumpf Glade Miller onionhammer Erik Johansson Andersson Hitesh Jasani Isak Andersson OldhamMade

Related Projects

aporia
A Nimrod IDE.
Nimble - Nimrod - GPL-2.0 - Published over 1 year ago - 135 stars
hex
A simple hex package for Nimrod
Nimble - Nimrod - MIT - Published 4 days ago
ipsumgenera
Static blog generator ala Jekyll.
Nimble - Nimrod - MIT - Published 4 days ago - 23 stars
moustachu
Mustache templating for Nimrod.
Nimble - Nimrod - MIT - Published 3 months ago - 4 stars
murmur
MurmurHash in pure Nimrod.
Nimble - Nimrod - MIT - Published over 1 year ago
веселые картинки развлекательные гифки интресные факты смешные видео смешные истории из соцсетей