Skip to content
This repository has been archived by the owner on Sep 5, 2023. It is now read-only.
/ phoon Public archive

A simple web framework for Nim πŸ‡βš‘

License

Notifications You must be signed in to change notification settings

ducdetronquito/phoon

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Phoon πŸ‡βš‘

Github Actions License

A simple web framework for Nim.

Usage

Nota Bene: Phoon is in its early stage, so every of its aspects is subject to changes πŸŒͺ️

Create an application:

import phoon

var app = new App

app.get("/",
    proc (ctx: Context) {.async.} =
        ctx.response.body("I am a boring home page")
)

app.post("/users",
    proc (ctx: Context) {.async.} =
        ctx.response.status(Http201).body("You just created a new user !")
)

app.get("/us*",
    proc (ctx: Context) {.async.} =
        ctx.response.body("Every URL starting with 'us' falls back here.")
)

app.get("/books/{title}",
    proc (ctx: Context) {.async.} =
        # You can retrieve parameters of the URL path
        var bookTitle = ctx.parameters.get("title")

        # You can also retrieve url-decoded query parameters
        let count = ctx.request.query("count")
        if count.isNone:
            ctx.response.body("Of course I read '" & bookTitle & "' !")
        else:
            ctx.response.body(
                "Of course I read '" & bookTitle & "', "
                "at least " & count & " times!"
            )
)

app.get("/cookies/",
    proc (ctx: Context) {.async.} =
        # You can send a cookie along the response
        ctx.response.cookie("size", "A big one πŸͺ")
)


# Chaining of callbacks for a given path
app.route("/hacks")
    .get(
        proc (ctx: Context) {.async.} =
            ctx.response.body("I handle GET requests")
    )
    .patch(
        proc (ctx: Context) {.async.} =
            ctx.response.body("I handle PATCH requests")
    )
    .delete(
        proc (ctx: Context) {.async.} =
            ctx.response.body("I handle DELETE requests")
    )


app.serve(port=8080)

Create a nested router

import phoon

var router = Router()

router.get("/users",
    proc (ctx: Context) {.async.} =
        ctx.response.body("Here are some nice users")
)

app.mount("/nice", router)

Register a middleware

import phoon

proc SimpleAuthMiddleware(next: Callback): Callback =
    return proc (ctx: Context) {.async.} =
        if ctx.request.headers.hasKey("simple-auth"):
            await next(ctx)
        else:
            ctx.response.status(Http401)

app.use(SimpleAuthMiddleware)

Error handling

import phoon

# Define a custom callback that is called when no registered route matched the incoming request path.
app.on404(
    proc (ctx: Context) {.async.} =
        ctx.response.status(Http404).body("Not Found Β―\\_(ツ)_/Β―")
)

# Define a custom callback that is called when an unhandled exception is raised within your code.
app.onError(
    proc (ctx: Context, error: ref Exception) {.async.} =
        ctx.response.status(Http500).body("Oops Β―\\_(ツ)_/Β―\r\n" & error.msg)
)

License

Phoon is released under the BSD Zero clause license. πŸŽ‰πŸ»