Le cadre Web de type Sinatra pour NIM. Jester fournit un DSL pour créer rapidement des applications Web dans NIM.
# example.nim
import htmlgen
import jester
routes:
get " / " :
resp h1 ( " Hello world " )Compiler et courir avec:
cd tests/example
nim c -r example.nim
Voir sur: localhost: 5000
Avant de déployer en production, assurez-vous d'exécuter votre application derrière un proxy inversé. Cette bibliothèque n'est pas encore durcie contre les exploits de sécurité HTTP, de sorte que les applications qui y sont écrites ne doivent pas être exposées à Internet public.
routes:
get " / " :
# do something here. Tous les itinéraires doivent être à l'intérieur d'un bloc routes .
Les itinéraires seront exécutés dans l'ordre où ils sont déclarés. Soyez donc prudent lorsque vous arrêtez.
Le chemin d'itinéraire peut contenir un modèle spécial ou juste une chaîne statique. Les modèles spéciaux sont presque identiques à ceux de Sinatra, la seule vraie différence est l'utilisation de @ au lieu de :
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 "Les modèles de Jester sont actuellement un peu plus limités, il n'y a pas de modèles de joker.
Vous pouvez utiliser le '?' Caractère pour signifier les pièces de chemin facultatives.
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 "Dans ce cas, vous voudrez peut-être faire le principal '/' Facultatif également, vous pouvez le faire en modifiant le modèle en "/ bonjour /? @ Nom?". Ceci est utile car Jester ne correspondra pas à "/ bonjour" si le principal '/' n'est pas facultatif.
Le regex peut également être utilisé comme modèle d'itinéraire. Les captures du sous-piste seront placées dans request.matches . Par exemple:
get re " ^ /([0-9]{2}) .html$ " :
resp request.matches[ 0 ] Cela correspondra aux URL du formulaire /15.html . Dans ce cas request.matches[0] aura 15 .
Jester prend en charge les conditions, mais ils sont limités à un modèle cond simple.
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. " Les corps d'itinéraire ont tous un objet request implicite. Cet objet est documenté dans jester.nim et la documentation peut être générée en exécutant nim doc jester.nim .
Le retour d'une réponse d'un itinéraire doit être effectué en utilisant l'une des fonctions suivantes:
resp .body , headers et / ou status et return d'appel.redirect la fonctionattachmentIl pourrait y en avoir plus. Jetez un œil à la documentation de Jester.nim pour plus d'informations.
Il est possible de ne pas utiliser la macro routes et de faire le routage vous-même.
Vous pouvez le faire en écrivant votre propre procédure match . Jetez un œil à l'exemple2 pour un exemple sur la façon de procéder.
Par défaut, Jester recherche des fichiers statiques dans ./public . Cela peut être remplacé à l'aide de la fonction setStaticDir . Les fichiers seront servis comme:
./public/css/style.css -> http://example.com/css/style.css
Remarque : Jester ne servira que des fichiers, qui sont lisibles par others . Sur Unix / Linux, vous pouvez vous assurer cela avec chmod o+r ./public/css/style.css .
Les cookies peuvent être définis à l'aide de la fonction setCookie .
get " / " :
# Set a cookie "test:value" and make it expire in 5 days.
setCookie ( " test " , @ " value " , daysForward ( 5 )) Ils sont ensuite accessibles à l'aide de la procédure request.cookies qui renvoie une Table[string, string] .
L'objet de demande contient toutes les informations sur la demande actuelle. Vous pouvez y accéder à partir d'un itinéraire à l'aide de la variable request . Il est défini comme:
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 * : MultiData # # 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 * : HttpMethod # # Request method, eg. HttpGet, HttpPost
settings * : Settings Un routeur personnalisé permet d'exécuter votre propre code d'initialisation et de transmettre des paramètres dynamiques à Jester avant de démarrer la boucle asynchrone.
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 ()Le code pour cela est assez similaire au code de Sinatra donné ici: http://help.github.com/post-receive-hooks/
import jester, json
routes:
post " / " :
var push = parseJson ( @ " payload " )
resp " I got some JSON: " & $ push