Created
December 23, 2017 15:03
-
-
Save mashingan/957137458dbe360a688495b357f343fd to your computer and use it in GitHub Desktop.
Basic REST with nest
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## | |
## Example of Nest that tracks how long routing takes | |
## | |
import nest | |
import logging | |
import asynchttpserver, strtabs, times, asyncdispatch, math | |
import httpcore | |
type | |
RequestHandler* = proc ( | |
req: Request, | |
headers : var HttpHeaders, | |
args : RoutingArgs | |
) : string {.gcsafe.} | |
# | |
# Initialization | |
# | |
var logger = newConsoleLogger() | |
let server = newAsyncHttpServer() | |
logger.log(lvlInfo, "****** Created server on ", getTime(), " ******") | |
# | |
# Set up mappings | |
# | |
var mapper = newRouter[RequestHandler]() | |
proc rootHandler(req: Request, headers: var HttpHeaders, args: RoutingArgs): | |
string {.gcsafe, procvar.} = | |
"You visited " & req.url.path | |
proc paramHandler(req: Request, headers: var HttpHeaders, args: RoutingArgs): | |
string {.gcsafe, procvar.} = | |
let id = args.pathArgs["id"] | |
echo "the id is ", id | |
"You visited " & req.url.path & " with id " & id | |
proc queryHandler(req: Request, headers: var HttpHeaders, args: RoutingArgs): | |
string {.gcsafe, procvar.} = | |
echo "The query given is ", args.queryArgs | |
"You visited " & req.url.path & " with query " & $args.queryArgs | |
proc patternHandler(req: Request, headers: var HttpHeaders, args: RoutingArgs): | |
string {.gcsafe, procvar.} = | |
"You visited " & req.url.path | |
mapper.map(rootHandler, $GET, "/") | |
mapper.map(paramHandler, $GET, "/param/{id}/ok") | |
mapper.map(queryHandler, $GET, "/query") | |
mapper.map(patternHandler, $GET, "/pattern/*/nice") | |
mapper.compress() | |
# | |
# Set up the dispatcher | |
# | |
# NOTE: these only use unsafe pointers to work with asynchttpserver, which requires full gcsafety in thread mode | |
let routerPtr = addr mapper | |
let loggerPtr = addr logger | |
proc dispatch(req: Request) {.async, gcsafe.} = | |
## | |
## Figures out what handler to call, and calls it | |
## | |
let startT = epochTime() | |
let matchingResult = routerPtr[].route(req.reqMethod, req.url, req.headers) | |
let endT = epochTime() | |
loggerPtr[].log(lvlDebug, "Routing took ", ((endT - startT) * 1000000), " microseconds") | |
if matchingResult.status == routingFailure: | |
await req.respond(Http404, "Resource not found") | |
else: | |
var | |
statusCode : HttpCode | |
headers = newHttpHeaders() | |
content : string | |
try: | |
content = matchingResult.handler(req, headers, matchingResult.arguments) | |
statusCode = Http200 | |
except: | |
loggerPtr[].log(lvlError, "Internal error occured:\n\t", getCurrentExceptionMsg()) | |
content = "Internal server error" | |
statusCode = Http500 | |
await req.respond(statusCode, content, headers) | |
# start up the server | |
logger.log(lvlInfo, "****** Started server on ", getTime(), " ******") | |
waitFor server.serve(Port(3000), dispatch) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment