A estrutura da web do tipo Sinatra para NIM. O Jester fornece uma DSL para criar rapidamente aplicativos da Web no NIM.
# example.nim
import htmlgen
import jester
routes:
get " / " :
resp h1 ( " Hello world " )Compilar e correr com:
cd tests/example
nim c -r example.nim
Ver em: localhost: 5000
Antes de implantar na produção, certifique -se de executar seu aplicativo por trás de um proxy reverso. Esta biblioteca ainda não foi endurecida contra explorações de segurança HTTP, para que os aplicativos escritos não sejam expostos à Internet pública.
routes:
get " / " :
# do something here. Todas as rotas devem estar dentro de um bloco de routes .
As rotas serão executadas na ordem em que sejam declaradas. Portanto, tenha cuidado ao interromper.
O caminho da rota pode conter um padrão especial ou apenas uma corda estática. Padrões especiais são quase idênticos aos de Sinatra, a única diferença real é o uso de @ em vez do : .
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 "Os padrões no Jester são atualmente um pouco mais limitados, não há padrões de curinga.
Você pode usar o '?' Personagem para significar peças de caminho opcional.
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 "Nesse caso, você também pode querer fazer do líder '/' opcional, você pode fazer isso alterando o padrão para "/hello/?@Nome?". Isso é útil porque o Jester não corresponde "/hello" se o líder '/' não for tomado opcional.
Regex também pode ser usado como um padrão de rota. As capturas de subpadra serão colocadas em request.matches quando uma rota for correspondente. Por exemplo:
get re " ^ /([0-9]{2}) .html$ " :
resp request.matches[ 0 ] Isso corresponderá aos URLs do formulário /15.html . Nesse caso, request.matches[0] será 15 .
O Jester suporta condições, no entanto, elas estão limitadas a um modelo cond simples.
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 os corpos da rota têm um objeto request implícita. Este objeto está documentado no Jester.nim e a documentação pode ser gerada executando nim doc jester.nim .
Retornar uma resposta de uma rota deve ser feita usando uma das seguintes funções:
resp .body , headers e/ou status e return de chamadas.redirect a funçãoattachmentPode haver mais. Dê uma olhada na documentação do Jester.nim para obter mais informações.
É possível não usar a macro routes e fazer o roteamento.
Você pode fazer isso escrevendo seu próprio procedimento match . Dê uma olhada no exemplo2 para um exemplo de como fazer isso.
Por padrão, Jester procura arquivos estáticos em ./public . Isso pode ser superestimado usando a função setStaticDir . Os arquivos serão servidos assim:
./public/css/style.css -> http://example.com/css/style.css
Nota : Jester servirá apenas arquivos, que são legíveis por others . No Unix/Linux, você pode garantir isso com chmod o+r ./public/css/style.css .
Os cookies podem ser definidos usando a função setCookie .
get " / " :
# Set a cookie "test:value" and make it expire in 5 days.
setCookie ( " test " , @ " value " , daysForward ( 5 )) Eles podem ser acessados usando o procedimento request.cookies , que retorna uma Table[string, string] .
O objeto de solicitação detém todas as informações sobre a solicitação atual. Você pode acessá -lo a partir de uma rota usando a variável request . É definido 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 Um roteador personalizado permite executar seu próprio código de inicialização e passar configurações dinâmicas para zombar antes de iniciar o loop assíncrono.
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 ()O código para isso é bem semelhante ao código para Sinatra fornecido aqui: http://help.github.com/post-receive--ooks/
import jester, json
routes:
post " / " :
var push = parseJson ( @ " payload " )
resp " I got some JSON: " & $ push