78 lines
2 KiB
Markdown
78 lines
2 KiB
Markdown
# What is this?
|
|
This is alba Http Server. It is like the threaded dispatchers of old, written in Nim. This includes the following:
|
|
|
|
- A simplified HTTP Server which does NOT use any ASYNC due to memory issues in Nim at the current moment. It also creates its own "Request" object compared to the one seen in the stdlib.
|
|
|
|
```nim
|
|
Request* = object
|
|
path* : Uri
|
|
verb* : HttpMethod
|
|
headers* : Table[string, string]
|
|
socket* : Socket
|
|
address* : string
|
|
```
|
|
- A threaded dispatcher which allocates requests to the thread with the least amount of requests currently pending. This is ideal for high-cpu using APIs.
|
|
|
|
It works using the following objects:
|
|
|
|
```nim
|
|
type
|
|
ThreadScheduler*[T] = object
|
|
initFunction : proc(): T{.gcsafe.}
|
|
paths : Table[string, proc(a : Request, b : T){.gcsafe.}]
|
|
ThreadHandler*[T] = object
|
|
Scheduler : ThreadScheduler[T]
|
|
communications: seq[ptr Channel[ptr Request]]
|
|
cpuCount : int
|
|
```
|
|
Where, T is the thread-local storage. For example
|
|
|
|
```nim
|
|
type ControllerData* = object
|
|
# Database connection for db operations
|
|
db : DbConn
|
|
# Standard response header, for all responses
|
|
headers : TableRef[string, string]
|
|
# Pre-generated response
|
|
dbInfo : string
|
|
# Pre-generated data
|
|
allUsers : seq[string]
|
|
```
|
|
All endpoints registered in paths must take the type [T] in.
|
|
|
|
# Usage
|
|
|
|
```nim
|
|
import albaHttpServer
|
|
import httpclient
|
|
import tables
|
|
import net
|
|
type MyObject = object
|
|
foo : string
|
|
bar : string
|
|
proc doThing(a : Request, b : MyObject) =
|
|
if a.verb != HttpGet:
|
|
a.respond(405, "")
|
|
a.respond(200, b.foo)
|
|
|
|
proc init() : MyObject =
|
|
result.foo = "hello"
|
|
result.bar = "world"
|
|
|
|
var paths : Table[string, proc(a: Request, b: MyObject){.gcsafe.}]
|
|
paths["/"] = doThing
|
|
let handler = initHandler[MyObject](init, paths)
|
|
|
|
let socket = newSocket()
|
|
socket.setSockOpt(OptReusePort, true)
|
|
socket.bindAddr(Port(5000))
|
|
socket.listen()
|
|
while true:
|
|
var request = getRequest(socket)
|
|
#Checks for invalid requests.
|
|
if request.isNone():
|
|
continue
|
|
else:
|
|
let req = request.get()
|
|
dispatch(req, handler)
|
|
```
|