Skip to content

Extend Context

Prologue provides flexible way to extend Context object. User-defined Context should inherit from the Context object.

A simple example

The following example shows how to make a UserContext object which contains a new data member of int type. You should use extend method to initialize the new attributes. Finally use app.run(UserContext) to register the type.

import prologue

type
  UserContext = ref object of Context
    data: int

# initialize data
method extend(ctx: UserContext) {.gcsafe.} =
  ctx.data = 999

proc hello*(ctx: Context) {.async.} =
  let ctx = UserContext(ctx)
  doAssert ctx.data == 999
  resp "<h1>Hello, Prologue!</h1>"

var app = newApp()
app.get("/", hello)
app.run(UserContext)

Make a middleware for personal use

import prologue

type
  UserContext = ref object of Context
    data: int

proc init(ctx: UserContext) =
  ctx.data = 12

proc experimentMiddleware(): HandlerAsync =
  result = proc(ctx: Context) {.async.} =
    let ctx = UserContext(ctx)
    doAssert ctx.data == 12
    inc ctx.data
    await switch(ctx)

method extend(ctx: UserContext) {.gcsafe.} =
  init(ctx)

proc hello*(ctx: Context) {.async.} =
  let ctx = UserContext(ctx)
  assert ctx.data == 13
  echo ctx.data
  resp "<h1>Hello, Prologue!</h1>"

var app = newApp()
app.use(experimentMiddleware())
app.get("/", hello)
app.run(UserContext)

Make a general purpose middleware

Notes: use prefix or suffix denoting data member to avoid conflicts with other middlewares.

# middleware for general purpose
type
  ExperimentContext = concept ctx
    ctx is Context
    ctx.data is int

proc init[T: ExperimentContext](ctx: T) =
  ctx.data = 12

proc experimentMiddleware[T: ExperimentContext](ctxType: typedesc[T]): HandlerAsync =
  result = proc(ctx: Context) {.async.} =
    let ctx = ctxType(ctx)
    doAssert ctx.data == 12
    inc ctx.data
    await switch(ctx)


type
  UserContext = ref object of Context
    data: int

method extend(ctx: UserContext) {.gcsafe.} =
  init(ctx)

proc hello*(ctx: Context) {.async.} =
  let ctx = UserContext(ctx)
  assert ctx.data == 13
  echo ctx.data
  resp "<h1>Hello, Prologue!</h1>"

var app = newApp()
app.use(experimentMiddleware(UserContext))
app.get("/", hello)
app.run(UserContext)