• Stars
    star
    1,569
  • Rank 29,832 (Top 0.6 %)
  • Language
    Nim
  • License
    MIT License
  • Created over 12 years ago
  • Updated 10 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A sinatra-like web framework for Nim.

🃏 Jester 🃏

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

# example.nim
import htmlgen
import jester

routes:
  get "/":
    resp h1("Hello world")

Compile and run with:

  cd tests/example
  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.

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

Note: Jester will only serve files, that are readable by others. On Unix/Linux you can ensure this with chmod o+r ./public/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 using the request.cookies procedure which returns a Table[string, string].

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:

Request* = 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.
  query*: string                ## Query string 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

Custom router

A custom router allows running your own initialization code and pass dynamic settings to Jester before starting the async loop.

import asyncdispatch, jester, os, strutils

router myrouter:
  get "/":
    resp "It's alive!"

proc main() =
  let port = paramStr(1).parseInt().Port
  let settings = newSettings(port=port)
  var jester = initJester(myrouter, settings=settings)
  jester.serve()

when isMainModule:
  main()

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, json

routes:
  post "/":
    var push = parseJson(@"payload")
    resp "I got some JSON: " & $push

More Repositories

1

choosenim

Tool for easily installing and managing multiple versions of the Nim programming language.
Nim
682
star
2

nimkernel

A small kernel written in Nim
Nim
615
star
3

httpbeast

A highly performant, multi-threaded HTTP 1.1 server written in Nim.
Nim
447
star
4

Aporia

IDE/Advanced text editor mainly focusing on support for the Nim programming language.
Nim
383
star
5

snake

A little snake game in Nim
Nim
207
star
6

nim-in-action-code

Nim in Action code samples
Nim
197
star
7

deauther

An interactive command-line deauther for macOS.
Nim
72
star
8

nim-opencv

Nim OpenCV wrapper
Nim
55
star
9

ipsumgenera

Static blog generator written in Nim
Nim
51
star
10

webdriver

Nim
46
star
11

gamelight

A set of simple modules for writing 2D games targeting JS/Android/iOS in Nim.
Nim
41
star
12

SimpleIRC

IRC Library for Haskell
Haskell
36
star
13

nimbox

Fork of https://notabug.org/vktec/nimbox
Nim
30
star
14

untar

Nim library for decompressing tar.gz files.
Nim
29
star
15

nael

Stack-based language similar to Factor.
Nim
26
star
16

prometheus

Prometheus instrumentation library for Nim
Nim
26
star
17

irc

Nim IRC module
Nim
22
star
18

binary_size

Shell
21
star
19

notifications

A small library for displaying notifications
Nim
17
star
20

pycloud

Experimental Pyodide fork which works in Cloudflare Workers
JavaScript
15
star
21

gbemulator

GameBoy emulator written in Nim
Nim
15
star
22

ElysiaBot

Modular Haskell IRC Bot
Haskell
12
star
23

nimbuild

Nim's build farm
Nim
12
star
24

sass

Nim bindings to the libsass C++ library
Nim
12
star
25

texttospeech

A Nim client for the Google Cloud Text to Speech API.
Nim
11
star
26

osinfo

Modules providing information about the OS for Nim
Nim
10
star
27

nim-jsonrpc

Nim
9
star
28

webasmio

A prototype library for selectively compiling Nim functions into Web Assembly
Nim
9
star
29

aoc2019

Advent of Code 2019 in Nim
Nim
7
star
30

analytics

A Google Analytics reporting library for Nim
Nim
7
star
31

tictactoe-rs

Tic Tac Toe in Rust
Rust
6
star
32

chirper.picheta.me

Browser extension which integrates Mastodon with Twitter.
HTML
6
star
33

xchat-exaile-script

A script which announces the currently played song in exaile. For xchat.
Python
5
star
34

stock_notifier

Nim
4
star
35

pwned

A client for the Pwned passwords API.
Nim
4
star
36

GeneticAlgorithms

Genetic algorithm experiments
Python
3
star
37

andromeda

ogame clone written in haskell
3
star
38

nyx

Old Python GTK IRC Client
Python
3
star
39

pb

Simple command line pastebin app.
Haskell
3
star
40

c4hbot

An IRC bot which lets you play Card Against Humanity. Written in Nim.
Nim
3
star
41

DynreckIRC

Lightweight, efficient and fast Python IRC Library
Python
2
star
42

vec

Nim
2
star
43

nim-urbanterror

Nimrod module for communicating with Urban Terror servers over UDP.
Nim
2
star
44

ld43

Nim
2
star
45

ld40

Nim
2
star
46

geckodriver-travis

Barebones example showing how to test a Jester app on Travis with Gecko driver.
Nim
2
star
47

MDSBot

Modular IRC Bot made in Python
Python
2
star
48

himari

My crappy toy OS
C
2
star
49

radiotap

Nim
2
star
50

dom96.github.com

2
star
51

adventofcode

Nim
2
star
52

nimrod-on-android

Attempt to run nimrod on the android platform
C
2
star
53

tinyrenderer.nim

C++
2
star
54

libclang

Nim
1
star
55

turingsim

Turing simulator written in Nim. Inspired by QUB's CSC2005.
Nim
1
star
56

qub-university-codesmash

http://shopkeep.github.io/qub-university-codesmash
Ruby
1
star
57

futurehack

It's a game thing.
C++
1
star
58

AELC

AEL(Awesome Esoteric Language) Interpreter
1
star
59

arduino

Messy repo with various Arduino experiments.
C++
1
star
60

oui

Parser for the official OUI file.
Nim
1
star
61

log2html

Tool for gathering information from HTTP server access logs.
1
star
62

CSC-Java

Java
1
star
63

corewlan

Nim
1
star
64

RPNCalc

A Reverse Polish Notation calculator made in various languages
Haskell
1
star
65

relnotesgen

Release notes generator
Nim
1
star
66

pyodide-worker-hello-world

Template to run Python via Pyodide on Cloudflare Workers
JavaScript
1
star