Синатроподобная веб-структура для NIM. Jester предоставляет DSL для быстрого создания веб -приложений в NIM.
# example.nim
import htmlgen
import jester
routes:
get " / " :
resp h1 ( " Hello world " )Скомпилируйте и бегите с:
cd tests/example
nim c -r example.nim
Просмотр: Localhost: 5000
Перед развертыванием в производстве убедитесь, что вы запустите свое приложение за обратным прокси. Эта библиотека еще не укрепляется от HTTP Security Exploits, поэтому приложения, написанные в ней, не должны подвергаться общедоступному Интернету.
routes:
get " / " :
# do something here. Все маршруты должны быть внутри блока routes .
Маршруты будут выполнены в приказе, который они объявлены. Так что будьте осторожны при остановке.
Путь маршрута может содержать специальный рисунок или просто статическую строку. Специальные закономерности практически идентичны Синатре, единственная реальная разница - это использование @ вместо : .
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 "Паттерны в Jester в настоящее время немного более ограничены, нет никаких схем с подстановочными знаками.
Вы можете использовать '?' символ, чтобы обозначить дополнительные части пути.
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 "В этом случае вы, возможно, захотите сделать ведущий «/» также необязательным, вы можете сделать это, изменив шаблон на «/hello/?@Name?». Это полезно, потому что Jester не будет соответствовать "/hello", если лидерство "/'не сделано необязательным.
В качестве шаблона маршрута также можно использовать в качестве маршрута. Захваты подчинения будут размещены в request.matches , когда маршрут соответствует. Например:
get re " ^ /([0-9]{2}) .html$ " :
resp request.matches[ 0 ] Это будет соответствовать URL -адресам формы /15.html . В этом случае request.matches[0] будет 15 .
Шута поддерживает условия, однако они ограничены простым шаблоном cond .
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. " У всех тел маршрута есть неявный объект request . Этот объект задокументирован в jester.nim, и документация может быть сгенерирована путем выполнения nim doc jester.nim .
Возврат ответа с маршрута должен быть выполнен с использованием одной из следующих функций:
resp .body , headers и/или status и вызова return .redirect функциюattachmentТам может быть больше. Посмотрите на документацию jester.nim для получения дополнительной информации.
Возможно, не использовать макрос routes и сделать маршрутизацию самостоятельно.
Вы можете сделать это, написав свою собственную процедуру match . Взгляните на пример2 для примера, как это сделать.
По умолчанию jester ищет статические файлы в ./public . Это можно переопределить, используя функцию setStaticDir . Файлы будут поданы так:
./public/css/style.css -> http://example.com/css/style.css
Примечание : Jester будет обслуживать только файлы, которые читаются others . На Unix/Linux вы можете убедиться, что это с chmod o+r ./public/css/style.css .
Файлы cookie могут быть установлены с помощью функции setCookie .
get " / " :
# Set a cookie "test:value" and make it expire in 5 days.
setCookie ( " test " , @ " value " , daysForward ( 5 )) Затем можно получить доступ с использованием процедуры request.cookies , которая возвращает Table[string, string] .
Объект запроса содержит всю информацию о текущем запросе. Вы можете получить доступ к нему из маршрута, используя переменную request . Это определено как:
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 Пользовательский маршрутизатор позволяет запустить свой собственный код инициализации и передавать динамические настройки в JESTER, прежде чем запустить Async Ploun.
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 ()Код для этого довольно похож на код для синатрой, данное здесь: http://help.github.com/post-receive-hooks/
import jester, json
routes:
post " / " :
var push = parseJson ( @ " payload " )
resp " I got some JSON: " & $ push