El marco web tipo Sinatra para NIM. Jester proporciona un DSL para crear rápidamente aplicaciones web en NIM.
# example.nim
import htmlgen
import jester
routes:
get " / " :
resp h1 ( " Hello world " )Compilar y ejecutar con:
cd tests/example
nim c -r example.nim
Ver en: Localhost: 5000
Antes de implementar en la producción, asegúrese de ejecutar su aplicación detrás de un proxy inverso. Esta biblioteca aún no está endurecida contra las exploits de seguridad HTTP, por lo que las aplicaciones escritas en ella no deben exponerse a Internet público.
routes:
get " / " :
# do something here. Todas las rutas deben estar dentro de un bloque routes .
Las rutas se ejecutarán en el orden en que se declaren. Así que tenga cuidado al detenerse.
La ruta de ruta puede contener un patrón especial o simplemente una cadena estática. Los patrones especiales son casi idénticos a los de Sinatra, la única diferencia real es el uso de @ en lugar del : .
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 "Los patrones en Jester son actualmente un poco más limitados, no hay patrones de comodín.
Puedes usar el '?' personaje para significar piezas de ruta opcionales.
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 "En este caso, es posible que desee hacer que el líder '/' sea opcional, puede hacerlo cambiando el patrón a "/hola/?@Name?". Esto es útil porque Jester no coincidirá con "/Hello" si el '/' líder no se hace opcional.
Regex también se puede usar como patrón de ruta. Las capturas de subpatrón se colocarán a request.matches . Por ejemplo:
get re " ^ /([0-9]{2}) .html$ " :
resp request.matches[ 0 ] Esto coincidirá con las URL de la forma /15.html . En este caso, 15 request.matches[0] .
Jester admite condiciones, sin embargo, se limitan a una plantilla 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. " Todos los cuerpos de ruta tienen un objeto request implícito. Este objeto está documentado en Jester.nim y la documentación se puede generar ejecutando nim doc jester.nim .
Devolver una respuesta de una ruta debe hacerse utilizando una de las siguientes funciones:
resp .body , headers y/o status y return de llamadas.redirectattachmentPuede haber más. Eche un vistazo a la documentación de Jester.nim para obtener más información.
Es posible no usar la macro routes y hacer el enrutamiento usted mismo.
Puede hacer esto escribiendo su propio procedimiento match . Eche un vistazo a Ejemplo2 para un ejemplo sobre cómo hacer esto.
Por defecto, Jester busca archivos estáticos en ./public . Esto se puede anular utilizando la función setStaticDir . Los archivos se servirán así:
./public/css/style.css -> http://example.com/css/style.css
Nota : Jester solo servirá archivos, que son legibles por others . En Unix/Linux puede asegurar esto con chmod o+r ./public/css/style.css .
Las cookies se pueden configurar utilizando la función setCookie .
get " / " :
# Set a cookie "test:value" and make it expire in 5 days.
setCookie ( " test " , @ " value " , daysForward ( 5 )) Luego se puede acceder a ellos utilizando el procedimiento de request.cookies que devuelve una Table[string, string] .
El objeto de solicitud contiene toda la información sobre la solicitud actual. Puede acceder a él desde una ruta utilizando la variable request . Se define como:
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 enrutador personalizado permite ejecutar su propio código de inicialización y pasar la configuración dinámica a Jester antes de comenzar el bucle Async.
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 ()El código para esto es bastante similar al código de Sinatra que se dio aquí: http://help.github.com/post-regeive-hooks/
import jester, json
routes:
post " / " :
var push = parseJson ( @ " payload " )
resp " I got some JSON: " & $ push